Ich möchte drei Ajax-Aufrufe in einem Klickereignis tätigen. Jeder Ajax-Aufruf führt eine bestimmte Operation aus und gibt Daten zurück, die für einen endgültigen Rückruf benötigt werden. Die Anrufe selbst sind nicht voneinander abhängig, sie können alle gleichzeitig ablaufen, ich hätte jedoch gerne einen letzten Rückruf, wenn alle drei abgeschlossen sind.
$('#button').click(function() {
fun1();
fun2();
fun3();
//now do something else when the requests have done their 'success' callbacks.
});
var fun1= (function() {
$.ajax({/*code*/});
});
var fun2 = (function() {
$.ajax({/*code*/});
});
var fun3 = (function() {
$.ajax({/*code*/});
});
Antworten:
Hier ist ein Rückrufobjekt, das ich geschrieben habe, in dem Sie entweder einen einzelnen Rückruf so einstellen können, dass er ausgelöst wird, sobald alle abgeschlossen sind, oder dass jeder seinen eigenen Rückruf hat und alle einmal abgeschlossen wird:
BEACHTEN
Seit jQuery 1.5+ können Sie die verzögerte Methode wie in einer anderen Antwort beschrieben verwenden:
Beispiel hier aufgeschoben
Für jQuery <1.5 funktioniert Folgendes oder wenn Sie Ihre Ajax-Anrufe zu unbekannten Zeiten abfeuern müssen, wie hier gezeigt, mit zwei Schaltflächen: Wird ausgelöst, nachdem beide Schaltflächen angeklickt wurden
[Verwendung]
für einen einzelnen Rückruf nach Abschluss: Arbeitsbeispiel
Jeder hat seinen eigenen Rückruf, wenn alle abgeschlossen sind: Arbeitsbeispiel
[Der Code]
quelle
setCallback
hinzuzufügen : P verwenden , um der Warteschlange mehr hinzuzufügen. Obwohl jetzt, wo ich darüber nachdenke ... ich sollte esaddCallback
oder so etwas nennen ... und nicht nur einstellen, da es der WarteschlangesingleCallback
Variable in der 2. Zeile nicht erforderlich? Oder fehlt mir etwas?Sieht so aus, als hätten Sie einige Antworten darauf, aber ich denke, hier gibt es etwas Erwähnenswertes, das Ihren Code erheblich vereinfacht. jQuery führte das
$.when
in v1.5 ein. Es sieht aus wie:Ich habe es hier nicht erwähnt gesehen, hoffe es hilft.
quelle
Ich sehe selbst nicht die Notwendigkeit eines Objekts. Einfach haben eine Variable, die eine ganze Zahl ist. Wenn Sie eine Anfrage starten, erhöhen Sie die Anzahl. Wenn man fertig ist, dekrementiere es. Wenn es Null ist, werden keine Anforderungen ausgeführt, sodass Sie fertig sind.
quelle
if (!--inProgress)
. Die richtige Version ist analog zuinProgress = inProgress - 1; if (inProgress == 0) { /* do stuff */ }
. Die kompakte Form kombiniert den Präfix-Dekrementierungsoperator (--
) und den Negationsoperator (!
), um "wahr" zu bewerten (und daher denif
Block auszuführen ), wenn das Dekrementieren zuinProgress
ergibtinProgress == 0
, und wertet sonst "falsch" aus (und tut daher nichts).Es ist erwähnenswert, dass, da
$.when
alle Ajax-Anforderungen als sequentielle Argumente (kein Array) erwartet werden, die Sie häufig mit folgender Adresse$.when
verwenden.apply()
:Dies liegt daran, dass
$.when
solche Argumente akzeptiert werdenUnd nicht so:
quelle
all
Methode oder ähnliches, aber ich mag das Kartenkonzept. Nett.Ich mag die Idee von hvgotcodes. Mein Vorschlag ist, einen generischen Inkrementierer hinzuzufügen, der die vollständige Nummer mit der benötigten Nummer vergleicht und dann den letzten Rückruf ausführt. Dies könnte in den endgültigen Rückruf eingebaut werden.
[Bearbeitet, um Namensaktualisierungen widerzuspiegeln.]
quelle
BEARBEITEN - Vielleicht ist die beste Option, einen Service-Endpunkt zu erstellen, der alles tut, was die drei Anforderungen tun. Auf diese Weise müssen Sie nur eine Anfrage ausführen, und alle Daten befinden sich dort, wo Sie sie in der Antwort benötigen. Wenn Sie feststellen, dass Sie immer wieder dieselben 3 Anfragen ausführen, möchten Sie wahrscheinlich diesen Weg gehen. Es ist oft eine gute Entwurfsentscheidung, einen Fassadendienst auf dem Server einzurichten, der häufig verwendete kleinere Serveraktionen zusammenfasst. Nur eine Idee.
Eine Möglichkeit besteht darin, vor dem Aufrufen von Ajax ein Synchronisierungsobjekt in Ihrem Klick-Handler zu erstellen. Etwas wie
Die Synchronisierung wird automatisch an den Umfang der Erfolgsaufrufe gebunden (Abschluss). Im Success-Handler erhöhen Sie die Anzahl, und wenn es 3 ist, können Sie die andere Funktion aufrufen.
Alternativ könnten Sie so etwas tun
Wenn jeder Erfolg ausgeführt wird, ändert sich der Wert in der Synchronisierung in true. Sie müssten die Synchronisierung überprüfen, um sicherzustellen, dass alle drei zutreffen, bevor Sie fortfahren.
Beachten Sie den Fall, dass einer Ihrer xhrs keinen Erfolg zurückgibt - Sie müssen dies berücksichtigen.
Eine weitere Option wäre, immer die letzte Funktion in Ihren Erfolgshandlern aufzurufen und sie auf die Synchronisierungsoption zugreifen zu lassen, um zu bestimmen, ob tatsächlich etwas getan werden soll. Sie müssten jedoch sicherstellen, dass die Synchronisierung im Umfang dieser Funktion liegt.
quelle
Ich habe vor einiger Zeit dieselbe Frage gestellt und hier einige gute Antworten erhalten: Der beste Weg, um nach einer Reihe von asynchronen XHR-Aufrufen einen Rückruf hinzuzufügen
quelle
Die Antworten auf dieser Seite haben mir einige gute Hinweise gegeben. Ich habe es ein wenig für meinen Gebrauch angepasst und dachte, ich könnte es teilen.
Hier gibt es einige Einschränkungen, aber für meinen Fall war es in Ordnung. Ich fand auch, dass es für fortgeschrittenere Sachen auch ein AOP-Plugin (für jQuery) gibt, das nützlich sein könnte: http://code.google.com/p/jquery-aop/
quelle
Ich bin heute auf dieses Problem gestoßen, und dies war mein naiver Versuch, bevor ich die akzeptierte Antwort sah.
quelle
Es ist nicht jquery (und es scheint, dass jquery eine praktikable Lösung hat), sondern nur als eine weitere Option ....
Ich hatte ähnliche Probleme bei der Arbeit mit SharePoint-Webdiensten. Oft müssen Sie Daten aus mehreren Quellen abrufen, um Eingaben für einen einzelnen Prozess zu generieren.
Um dies zu lösen, habe ich diese Art von Funktionalität in meine AJAX-Abstraktionsbibliothek eingebettet. Sie können einfach eine Anforderung definieren, die nach Abschluss eine Reihe von Handlern auslöst. Jede Anforderung kann jedoch mit mehreren http-Aufrufen definiert werden. Hier ist die Komponente (und detaillierte Dokumentation):
DPAJAX bei DepressedPress.com
In diesem einfachen Beispiel wird eine Anforderung mit drei Aufrufen erstellt und diese Informationen in der Anrufreihenfolge an einen einzelnen Handler übergeben:
Beachten Sie, dass im Gegensatz zu vielen anderen Lösungen (einschließlich der "Wann" -Lösung in jquery) diese Methode kein einzelnes Threading der getätigten Aufrufe erzwingt - jede wird weiterhin so schnell (oder so langsam) ausgeführt, wie es die Umgebung zulässt Der einzelne Handler wird jedoch nur aufgerufen, wenn alle vollständig sind. Es unterstützt auch das Festlegen von Zeitlimitwerten und Wiederholungsversuchen, wenn Ihr Dienst ein wenig unzuverlässig ist.
Ich fand es wahnsinnig nützlich (und aus Code-Sicht unglaublich einfach zu verstehen). Keine Verkettung mehr, kein Zählen von Anrufen und Speichern der Ausgabe mehr. Einfach "einstellen und vergessen".
quelle
Ok, das ist alt, aber bitte lassen Sie mich meine Lösung beitragen :)
Es funktioniert auch mit Funktionen, die einen Rückruf haben. Sie setzen den syncCount und rufen die Funktion sync (...) im Rückruf jeder Aktion auf.
quelle
Ich habe einen einfacheren Weg gefunden, ohne zusätzliche Methoden zum Anordnen einer Warteschlange zu benötigen.
JS
PHP (ajax1.php)
PHP (ajax2.php)
quelle
Standardmäßig werden alle Anforderungen asynchron gesendet (dh dies ist standardmäßig auf true gesetzt). Wenn Sie synchrone Anforderungen benötigen, setzen Sie diese Option auf
false
. Domänenübergreifende Anforderungen unddataType: "jsonp"
Anforderungen unterstützen den synchronen Betrieb nicht. Beachten Sie, dass synchrone Anforderungen den Browser vorübergehend sperren und alle Aktionen deaktivieren können, während die Anforderung aktiv ist. Ab jQuery 1.8 ist die Verwendung vonasync: false
mit jqXHR ($.Deferred
) veraltet. Sie müssen die Rückrufoptionen Erfolg / Fehler / Vollständig anstelle der entsprechenden Methoden des jqXHR- Objekts wiejqXHR.done()
oder veraltet verwendenjqXHR.success()
.quelle
Es tut mir leid, aber ich kann nicht erklären, was ich getan habe, weil ich ein Koreaner bin, der nicht einmal ein Wort auf Englisch sprechen kann. aber ich denke, Sie können es leicht verstehen.
quelle