jQuery's Deferred
verfügt über zwei Funktionen, mit denen die asynchrone Verkettung von Funktionen implementiert werden kann:
then()
deferred.then( doneCallbacks, failCallbacks ) Returns: Deferred
doneCallbacks Eine Funktion oder ein Array von Funktionen, die aufgerufen wird, wenn der verzögerte Wert aufgelöst wird.
failCallbacks Eine Funktion oder ein Array von Funktionen, die aufgerufen wird, wenn Deferred abgelehnt wird.
pipe()
deferred.pipe( [doneFilter] [, failFilter] ) Returns: Promise
doneFilter Eine optionale Funktion, die aufgerufen wird, wenn Deferred aufgelöst wird.
failFilter Eine optionale Funktion, die aufgerufen wird, wenn Deferred abgelehnt wird.
Ich weiß, dass then()
es schon etwas länger her ist, pipe()
daher muss letzteres einen zusätzlichen Nutzen bringen, aber was genau der Unterschied ist, entgeht mir. Beide verwenden fast dieselben Rückrufparameter, obwohl sie sich im Namen unterscheiden und der Unterschied zwischen der Rückgabe von a Deferred
und der Rückgabe von a Promise
gering erscheint.
Ich habe die offiziellen Dokumente immer und immer wieder gelesen, finde sie aber immer zu "dicht", um mich wirklich zu beschäftigen, und die Suche hat viele Diskussionen über das eine oder andere Feature ergeben, aber ich habe nichts gefunden, was den Unterschied wirklich verdeutlicht Vor- und Nachteile von jedem.
Wann ist es besser zu verwenden then
und wann ist es besser zu verwenden pipe
?
Zusatz
Felix 'hervorragende Antwort hat wirklich geholfen zu klären, wie sich diese beiden Funktionen unterscheiden. Aber ich frage mich, ob es Zeiten gibt, in denen die Funktionalität von der von then()
vorzuziehen ist pipe()
.
Es ist offensichtlich, dass dies pipe()
mächtiger ist als then()
und es scheint, dass Ersteres alles kann, was Letzteres tun kann. Ein Grund für die Verwendung then()
könnte sein, dass sein Name seine Rolle als Beendigung einer Funktionskette widerspiegelt, die dieselben Daten verarbeitet.
Aber gibt es einen Anwendungsfall, bei dem then()
das Original zurückgegeben Deferred
werden muss, was pipe()
aufgrund der Rückgabe eines neuen Originals nicht möglich ist Promise
?
quelle
Antworten:
Da sich jQuery 1.8
.then
genauso verhält wie.pipe
:und
Die folgenden Beispiele könnten für einige noch hilfreich sein.
Sie dienen verschiedenen Zwecken:
.then()
ist immer dann zu verwenden, wenn Sie mit dem Ergebnis des Prozesses arbeiten möchten, dh wie in der Dokumentation angegeben, wenn das zurückgestellte Objekt aufgelöst oder abgelehnt wird. Es ist dasselbe wie mit.done()
oder.fail()
.Sie würden das Ergebnis irgendwie
.pipe()
(vor) filtern . Der Rückgabewert eines Rückrufs an.pipe()
wird als Argument an die Rückrufedone
und übergebenfail
. Es kann auch ein anderes zurückgestelltes Objekt zurückgeben, und die folgenden Rückrufe werden für dieses zurückgestellte Objekt registriert.Das ist nicht der Fall mit
.then()
(oder.done()
,.fail()
), die Rückgabewerte der registrierten Rückrufe werden einfach ignoriert.Es ist also nicht so, dass Sie entweder
.then()
oder verwenden.pipe()
. Du könnten verwenden.pipe()
als für die gleichen Zwecke ,.then()
aber die Umkehrung nicht gilt.Beispiel 1
Das Ergebnis einer Operation ist ein Array von Objekten:
und Sie möchten das Minimum und Maximum der Werte berechnen. Nehmen wir an, wir verwenden zwei
done
Rückrufe:In beiden Fällen müssen Sie die Liste durchlaufen und den Wert aus jedem Objekt extrahieren.
Wäre es nicht besser, die Werte vorher irgendwie zu extrahieren, damit Sie dies nicht in beiden Rückrufen einzeln tun müssen? Ja! Und dafür können wir Folgendes verwenden
.pipe()
:Natürlich ist dies ein erfundenes Beispiel und es gibt viele verschiedene (vielleicht bessere) Möglichkeiten, um dieses Problem zu lösen, aber ich hoffe, es veranschaulicht den Punkt.
Beispiel 2
Betrachten Sie Ajax-Anrufe. Manchmal möchten Sie einen Ajax-Aufruf einleiten, nachdem ein vorheriger abgeschlossen wurde. Eine Möglichkeit besteht darin, den zweiten Anruf innerhalb eines
done
Rückrufs zu tätigen :Nehmen wir nun an, Sie möchten Ihren Code entkoppeln und diese beiden Ajax-Aufrufe in eine Funktion einfügen:
Sie möchten das zurückgestellte Objekt verwenden, um anderen Code, der aufruft
makeCalls
, das Anhängen von Rückrufen für den zweiten Ajax-Aufruf zu ermöglichenhätte nicht den gewünschten Effekt, da der zweite Anruf innerhalb eines
done
Rückrufs getätigt wird und von außen nicht zugänglich ist.Die Lösung wäre
.pipe()
stattdessen:Mithilfe von können
.pipe()
Sie jetzt Rückrufe an den "inneren" Ajax-Anruf anhängen, ohne den tatsächlichen Ablauf / die Reihenfolge der Anrufe offenzulegen.Im Allgemeinen bieten zurückgestellte Objekte eine interessante Möglichkeit, Ihren Code zu entkoppeln :)
quelle
pipe
Filterungthen
nicht möglich ist. Aber beim Googeln dieser Themen scheinen sie sich dafür entschieden zu haben, es zu nennen,pipe
anstattfilter
die Filterung als eine Art Bonus-Extra zu betrachten, das damit einherging , währendpipe
der wahre Zweck deutlicher angegeben wurde. Es scheint also, dass es neben der Filterung noch andere Unterschiede geben sollte. (result values;
return values;
.then()
die gleichen Daten, inresult
denen Sie jedes Mal filtern; wohingegen im unteren Beispiel.pipe()
einige der Daten entfernt werden,result
bevor sie weitergegeben werden, daresult
die beiden folgenden.then()
s empfangen werden?.pipe()
. Wenn der Rückruf ein zurückgestelltes Objekt zurückgibt, werden nachfolgende erledigte oder fehlgeschlagene Rückrufe für dieses Objekt registriert. Ich werde ein weiteres Beispiel hinzufügen. bearbeiten: bezüglich Ihres zweiten Kommentars: ja.pipe()
, währendthen()
eher wie ein Blattknoten am Ende der Sie Ihre Daten verwenden müssen und es fließt nicht weiter, und das trotz der Tatsache , dassthen()
Renditen einDeferred
es tatsächlich nicht verwendet / sinnvoll? Wenn dies richtig ist, kann es hilfreich sein, zu verdeutlichen, dass/* do something with "min"/"max" */
in jede ".then () -Klausel" so etwas aufgenommen wird.Es gibt keinen Fall, in dem Sie
then()
über verwenden müssenpipe()
. Sie können jederzeit festlegen, dass der übergebene Wert ignoriertpipe()
wird. Bei der Verwendung kann es zu geringfügigen Leistungseinbußen kommenpipe
- dies ist jedoch unwahrscheinlich.Es könnte also so aussehen, als könnten Sie
pipe()
in beiden Fällen einfach immer verwenden . Durch die Verwendung vonpipe()
kommunizieren Sie jedoch anderen Personen, die Ihren Code lesen (einschließlich Ihnen selbst, in sechs Monaten), dass der Rückgabewert eine gewisse Bedeutung hat. Wenn Sie es verwerfen, verletzen Sie dieses semantische Konstrukt.Es ist, als hätte man eine Funktion, die einen Wert zurückgibt, der niemals verwendet wird: verwirrend.
Verwenden
then()
Sie also, wann Sie sollten undpipe()
wann Sie ...quelle
$(function () { $.when(getPosition()) .pipe(lookupCountry) .then(displayResults); });
"Beachten Sie, dass Pipe anders ist als dann, weil Pipe ein neues Versprechen zurückgibt. "Tatsächlich stellt sich heraus, dass der Unterschied zwischen
.then()
und.pipe()
als unnötig erachtet wurde und dass er mit jQuery Version 1.8 identisch ist.Aus einem Kommentar von
jaubourg
in jQuerys Bug-Tracker- Ticket # 11010 "MAKE DEFERRED.THEN == DEFERRED.PIPE LIKE PROMISE / A":(Emphassis Mine)
quelle