2012-04-20 11 views
18

Ich habe über Abgegrenzte und Versprechen in jQuery gelesen, aber ich habe es noch nicht verwendet.Understanding Deferred.pipe()

Ich habe alles sehr gut verstanden, aber die Methode Rohr. Ich habe wirklich nicht verstanden, was es ist.

Könnte mir bitte helfen, zu verstehen, was es tut und wo es verwendet werden könnte?

Ich weiß, es gibt eine Frage mit dem Titel genau so (here), aber es ist nicht das gleiche. Ich bitte um Hilfe, um es und ein Beispiel zu verstehen. Das Ziel der anderen Frage ist zu verstehen, warum es in einem bestimmten Fall nicht funktioniert.

+1

Haben Sie http://api.jquery.com/deferfer.pipe/ überprüft? – Armatus

+1

Ja, ich habe. Ich habe von dort angefangen. – Diego

+0

Beachten Sie, dass 'deferred.pipe' und' defered.when' seit v1.8 gleichwertig sind (siehe http://stackoverflow.com/questions/12011925/pipe-and-then-documentation-vs-reality-in-jquery- 1-8) – tokland

Antwort

46

Grundsätzlich ist Deferred.pipe() ein asynchrones Äquivalent zu $.map(). Es projiziert neue Werte von anderen Werten, die als Eingabe bereitgestellt werden, aber sein Zweck ist es, mit Fortsetzungen verwendet zu werden.

Beginnen wir mit einem Beispiel, das nur $.each() erfordert und eine AJAX-Anforderung ausgibt, die ein einfaches Objekt zurückgibt. Für jede Eigenschaft dieses Objekts möchten wir das Formularsteuerelement, dessen id Attribut der Schlüssel der Eigenschaft ist, um seinen Wert auf den Wert der Eigenschaft festzulegen.Wir können so etwas wie schreiben:

$.ajax("your/url", { 
    dataType: "json" 
}).done(function(data) { 
    $.each(data, function(key, value) { 
     $("#" + key).val(value); 
    }); 
}); 

Nun lassen Sie uns sagen, dass wir eine Funktion auf die Werte anwenden möchten, bevor Sie die Formular-Steuerelemente zu aktualisieren. Wenn wir das vor Ort machen, wir müssen nur schreiben:

$.ajax("your/url", { 
    dataType: "json" 
}).done(function(data) { 
    $.each(data, function(key, value) { 
     // doSomethingWith() projects values synchronously, as map() does. 
     $("#" + key).val(doSomethingWith(value)); 
    }); 
}); 

Aber was passiert, wenn doSomethingWith() nicht clientseitige implementiert, aber serverseitige durch einen anderen Web-Service? In diesem Fall möchten wir den Kontrollfluss in die zweite AJAX-Anfrage eingliedern und die Formularsteuerelemente nur aktualisieren, wenn die zweite Anfrage zurückgegeben wurde. Deferred.pipe() macht so einfach:

$.ajax("your/url", { 
    dataType: "json" 
}).pipe(function(theOriginalData) { 
    return $.ajax("your/web/service/doSomethingWith", { 
     data: theOriginalData, 
     dataType: "json" 
    }); 
}).done(function(theFinalData) { 
    $.each(theFinalData, function(key, value) { 
     $("#" + key).val(value); 
    }); 
}); 
+2

Große Antwort !! Vielen Dank! – Diego

+0

Sind diese 2 Beispiele eigentlich funktional gleich? Diese Vorstellung, dass die anon-Funktion, die den Webservice innerhalb des '.pipe'-Aufrufs * iterativ * aufruft, neu für mich ist. Ich weiß, dass ab jQuery 1.8 die '.pipe'-Methode veraltet ist und durch' .then' ersetzt wird, aber könnten Sie die funktionalen Unterschiede zwischen der '.each' &' .pipe'-Version näher erläutern, wenn sie existieren? Wie werden die Rückgabedaten aus dem ersten GET durch '.pipe 'aufgezählt? Wenn dies nicht funktioniert, wäre es hilfreich, klarzustellen, dass die '.pipe'-Version, die einen Webservice aufruft, nicht iterativ, sondern als Stapelverarbeitung arbeitet. – JoeBrockhaus

+0

@Joe, die Beispiele sind "funktional" gleich, nur der erste verarbeitet die Werte synchron, während der zweite das asynchron (über einen Webservice) macht. 'pipe()' (und jetzt 'then()') wird nur aufgerufen, wenn die erste Anfrage zurückgegeben wurde, so dass die ursprünglichen Daten bereits verfügbar sind. Der Code * sieht * iterativ aus, aber 'pipe()', das ein Versprechen zurückgibt, bedeutet, dass der Rest der Pipeline darauf wartet, dass dieses Versprechen erfüllt (oder abgelehnt) wird. –

1

Hiya ist es das, was Sie für :)

[schön Lesen] http://www.bennadel.com/blog/2255-Using-jQuery-s-Pipe-Method-To-Change-Deferred-Resolution.htm

Zitat

Das Rohr() Methode sowohl für den Erfolg suchen, um einen Filter liefert und Fehler Auflösungen (der AJAX-Anfrage). Wenn die ursprüngliche Auflösung Erfolg ist, übergibt der Pipe() - Filter eine wirklich erfolgreiche Antwort durch; oder es ändert die Auflösung und gibt eine neue abgewiesene Zusage zurück. Dann wird, wenn die ursprüngliche Anfrage ein Fehler war, die in unserer API wirklich unerwartet sein würde, das Rohr() Filter passiert einfach durch eine normalisierte API-Antwort Struktur ....

Stapelverbindung mit BeispielUnderstanding jQuery Deferred.pipe() (hat jfiddle drin)

Understanding Deferred & Versprechen? siehe hier bittehttp://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/

JQuery offizielle API Seitehttp://api.jquery.com/deferred.pipe/ (mit Beispielen)

Beschreibung: Utility-Methode zum Filtern und/oder Ketten Deferreds.

Die Methode deferred.pipe() gibt eine neue Zusage zurück, die den Status und die Werte einer durch eine Funktion zurückgestellten Funktion filtert. Die Funktionen doneFilter und failFilter filtern den Status der zurückgewiesenen/ zurückgewiesenen Status und Werte des ursprünglichen deferred. Ab jQuery 1.7 akzeptiert die Methode auch eine progressFilter-Funktion, um alle Aufrufe an die ursprünglichen Methoden "notify" oder "notifyWith" des Typs "deferred" zu filtern.

11

OK, ich viel Referenzmaterial in einer anderen Antwort hier sehen, aber Lesen ist manchmal nicht die gleiche wie Verständnis.

Ich finde es am einfachsten, ein Versprechen und die Anwendung von .done() zu ihr gegen .pipe() zu denken. Jeder wirkt anders. Wenn ich promise.done (function (result) {...}) nehme, kann ich danach weitere .done() 's oder .fail()' s anhängen, da jeder Aufruf von .done() oder .fail () gibt genau das gleiche Versprechen zurück. So wird jede Funktion an das ursprüngliche Versprechen gebunden und ob es aufgelöst oder zurückgewiesen wird.

Nun, Gegensatz zu .pipe(). Wenn ich promise.pipe (function (result) {...}) nehme, dann ist das, was aus der .pipe() kommt, ein ganz neues Versprechen! Wenn ich dann .done() oder .fail() an dieses Versprechen anschließe, erhalten diese Funktionen die modifizierte Version der Ergebnisse, die das .pipe() zurückgibt, nicht die ursprünglichen Ergebnisse.

Also .pipe() ist meiner Erfahrung nach selten erforderlich. Das einzige Mal, wenn es wirklich nützlich ist, wenn Sie die Daten ändern müssen, die von einem Versprechen zurückgegeben werden, bevor anderer Code es sieht (z. B. einige Ergebnisse eines AJAX-Aufrufs auf der Clientseite ändern, bevor jeder andere clientseitige Code funktioniert) es) oder wenn Sie Dinge sequenzieren müssen. Beispiel: Nachdem Versprechen A aufgelöst oder abgelehnt wurde, führen Sie eine weitere Aktion durch. Erst dann möchten wir, dass anderer Code schließlich ausgelöst wird. Der gesamte andere Code ist an das Versprechen B angehängt, das aus dem Aufruf .pipe() stammt.

Hier ist eine neuere Frage, wo ein anderer Benutzer Probleme mit der Verwendung von Versprechen und .pipe() /. Done()/.when() hatte und ich versuchte, einen Code zur Verfügung zu stellen, um die Verwendung von jedem in einer jsFiddle zu verdeutlichen : Do something when all deferreds are resolved

+1

Große Antwort, genau was ich war versuchen t o herauszufinden, warum verwenden Sie. pipe() anstelle von .done(). – uglymunky