jQuery 1.5 bringt das neue Rechnungsabgrenzungs Objekt und die beigefügten Methoden .when
, .Deferred
und ._Deferred
.
Für diejenigen, die noch nicht verwendet .Deferred
haben, habe ich die Quelle dafür mit Anmerkungen versehen .
Was sind die möglichen Verwendungsmöglichkeiten dieser neuen Methoden, wie passen wir sie in Muster an?
Ich habe die API und die Quelle bereits gelesen und weiß, was sie bewirkt. Meine Frage ist, wie wir diese neuen Funktionen im alltäglichen Code verwenden können.
Ich habe ein einfaches Beispiel für eine Pufferklasse, die die AJAX-Anforderung der Reihe nach aufruft. (Der nächste Start nach dem vorherigen endet).
/* Class: Buffer
* methods: append
*
* Constructor: takes a function which will be the task handler to be called
*
* .append appends a task to the buffer. Buffer will only call a task when the
* previous task has finished
*/
var Buffer = function(handler) {
var tasks = [];
// empty resolved deferred object
var deferred = $.when();
// handle the next object
function handleNextTask() {
// if the current deferred task has resolved and there are more tasks
if (deferred.isResolved() && tasks.length > 0) {
// grab a task
var task = tasks.shift();
// set the deferred to be deferred returned from the handler
deferred = handler(task);
// if its not a deferred object then set it to be an empty deferred object
if (!(deferred && deferred.promise)) {
deferred = $.when();
}
// if we have tasks left then handle the next one when the current one
// is done.
if (tasks.length > 0) {
deferred.done(handleNextTask);
}
}
}
// appends a task.
this.append = function(task) {
// add to the array
tasks.push(task);
// handle the next task
handleNextTask();
};
};
Ich suche nach Demonstrationen und Verwendungsmöglichkeiten von .Deferred
und .when
.
Es wäre auch schön, Beispiele zu sehen ._Deferred
.
Das Verknüpfen mit der neuen jQuery.ajax
Quelle für Beispiele ist Betrug.
Mich interessiert besonders, welche Techniken verfügbar sind, wenn wir abstrahieren, ob eine Operation synchron oder asynchron ausgeführt wird.
quelle
._Deferred
ist einfach das wahre "Zurückgestellte Objekt", das.Deferred
verwendet. Es ist ein internes Objekt, das Sie höchstwahrscheinlich nie brauchen werden.Antworten:
Der beste Anwendungsfall, den ich mir vorstellen kann, ist das Zwischenspeichern von AJAX-Antworten. Hier ist ein modifiziertes Beispiel aus Rebecca Murpheys Intro-Post zum Thema :
Grundsätzlich gilt, wenn der Wert bereits einmal angefordert wurde, bevor er sofort aus dem Cache zurückgegeben wird. Andernfalls ruft eine AJAX-Anforderung die Daten ab und fügt sie dem Cache hinzu. Das
$.when
/.then
kümmert sich nicht darum; Alles, worüber Sie sich Sorgen machen müssen, ist die Verwendung der Antwort, die.then()
in beiden Fällen an den Handler übergeben wird.jQuery.when()
behandelt ein Nicht-Versprechen / Zurückgestellt als Abgeschlossen und führt sofort eines.done()
oder.then()
in der Kette aus.Zurückgestellte sind perfekt, wenn die Aufgabe asynchron ausgeführt werden kann oder nicht und Sie diese Bedingung aus dem Code abstrahieren möchten.
Ein weiteres Beispiel aus der
$.when
Praxis mit dem Helfer:quelle
cache[ val ]
ein Versprechen zurückgibt (die jquery-Dokumentation besagt, dass der Parameter die vom Absender zurückgegebenen Daten sind), was dies bedeutet Der Mitgliederzugriff von.then
Will Fehler ... richtig? Was vermisse ich?Hier ist eine etwas andere Implementierung eines AJAX-Cache als in der Antwort von ehynd .
Wie in der Folgefrage von FortuneRice erwähnt, hat die Implementierung von ehynd nicht tatsächlich mehrere identische Anforderungen verhindert, wenn die Anforderungen ausgeführt wurden, bevor eine von ihnen zurückgekehrt war. Das ist,
wird höchstwahrscheinlich zu 3 AJAX-Anforderungen führen, wenn das Ergebnis für "xxx" noch nicht zuvor zwischengespeichert wurde.
Dies kann gelöst werden, indem anstelle des Ergebnisses die verzögerten Anforderungen der Anforderung zwischengespeichert werden:
quelle
Ein Aufgeschobener kann anstelle eines Mutex verwendet werden. Dies entspricht im Wesentlichen den Szenarien für die Verwendung mehrerer Ajax.
MUTEX
VERZÖGERT
Achten Sie bei der Verwendung eines Deferred nur als Mutex auf Leistungseinbußen (http://jsperf.com/deferred-vs-mutex/2). Obwohl sich die Bequemlichkeit sowie die zusätzlichen Vorteile eines verzögerten Einsatzes durchaus lohnen und bei der tatsächlichen (benutzergesteuerten ereignisbasierten) Nutzung die Auswirkungen auf die Leistung nicht spürbar sein sollten.
quelle
Dies ist eine Antwort für sich selbst, aber ich habe einige Monate damit verbracht, dies zu untersuchen und die Ergebnisse auf der jQuery-Konferenz in San Francisco 2012 vorzustellen.
Hier ist ein kostenloses Video des Vortrags:
https://www.youtube.com/watch?v=juRtEEsHI9E
quelle
Eine andere Verwendung, die ich sinnvoll eingesetzt habe, ist das Abrufen von Daten aus mehreren Quellen. Im folgenden Beispiel rufe ich mehrere unabhängige JSON-Schemaobjekte ab, die in einer vorhandenen Anwendung zur Validierung zwischen einem Client und einem REST-Server verwendet werden. In diesem Fall möchte ich nicht, dass die browserbasierte Anwendung mit dem Laden von Daten beginnt, bevor alle Schemas geladen sind. $ .when.apply (). then () ist dafür perfekt. Vielen Dank an Raynos für Hinweise zur Verwendung von then (fn1, fn2) zur Überwachung auf Fehlerzustände.
quelle
Ein weiteres Beispiel
Deferred
für die Implementierung eines Caches mit s für jede Art von Berechnung (normalerweise einige leistungsintensive oder lang laufende Aufgaben):Hier ist ein Beispiel für die Verwendung dieser Klasse, um eine (simulierte schwere) Berechnung durchzuführen:
Der gleiche zugrunde liegende Cache kann zum Zwischenspeichern von Ajax-Anforderungen verwendet werden:
Sie können mit dem obigen Code in dieser jsFiddle spielen .
quelle
1) Verwenden Sie diese Option, um eine geordnete Ausführung von Rückrufen sicherzustellen:
2) Verwenden Sie diese Option, um den Status der App zu überprüfen:
quelle
Sie können ein zurückgestelltes Objekt verwenden, um ein flüssiges Design zu erstellen, das in Webkit-Browsern gut funktioniert. Webkit-Browser lösen ein Größenänderungsereignis für jedes Pixel aus, dessen Fenstergröße geändert wird, im Gegensatz zu FF und IE, die das Ereignis nur einmal für jede Größenänderung auslösen. Infolgedessen haben Sie keine Kontrolle über die Reihenfolge, in der die an Ihr Fenstergrößenänderungsereignis gebundenen Funktionen ausgeführt werden. So etwas löst das Problem:
Dadurch wird die Ausführung Ihres Codes so serialisiert, dass er wie beabsichtigt ausgeführt wird. Achten Sie auf Fallstricke, wenn Sie Objektmethoden als Rückruf an einen Zurückgestellten übergeben. Sobald eine solche Methode als Rückruf auf verzögert ausgeführt wird, wird die 'this'-Referenz mit Bezug auf das zurückgestellte Objekt überschrieben und bezieht sich nicht mehr auf das Objekt, zu dem die Methode gehört.
quelle
resizeQueue.done(resizeAlgorithm)
sind genau so wieresizeAlgorithm
. Es ist eine völlige Täuschung!.done
sein.Sie können es auch in Bibliotheken von Drittanbietern integrieren, die JQuery verwenden.
Eine solche Bibliothek ist Backbone, die Deferred in ihrer nächsten Version tatsächlich unterstützen wird.
quelle
read more here
anstelle vonon my blog
. Dies ist eine bessere Vorgehensweise und kann Ihnen die Antwort vor (versehentlich) Spam ersparen. :)Ich habe Deferred gerade in echtem Code verwendet. Im Projekt jQuery Terminal habe ich die Funktion exec, die vom Benutzer definierte Befehle aufruft (wie er sie eingegeben und die Eingabetaste gedrückt hat). Ich habe der API Zurückgestellte hinzugefügt und exec mit Arrays aufgerufen. so was:
oder
Die Befehle können asynchronen Code ausführen, und exec muss den Benutzercode der Reihe nach aufrufen. Meine erste API verwendet zwei Pausen- / Wiederaufnahme-Aufrufe und in der neuen API rufe ich diese automatisch auf, wenn der Benutzer das Versprechen zurückgibt. Benutzercode kann also einfach verwendet werden
oder
Ich benutze folgenden Code:
dalyed_commands wird in der Resume-Funktion verwendet, die exec mit allen dalyed_commands erneut aufruft.
und ein Teil der Befehlsfunktion (ich habe nicht verwandte Teile entfernt)
quelle
Die Antwort von ehynds funktioniert nicht, da die Antwortdaten zwischengespeichert werden. Es sollte das jqXHR zwischenspeichern, was auch ein Versprechen ist. Hier ist der richtige Code:
Die Antwort von Julian D. wird korrekt funktionieren und ist eine bessere Lösung.
quelle