Wie lasse ich eine Funktion warten, bis alle jQuery Ajax-Anforderungen in einer anderen Funktion ausgeführt wurden?
Kurz gesagt, ich muss warten, bis alle Ajax-Anforderungen ausgeführt wurden, bevor ich die nächste ausführe. Aber wie?
javascript
jquery
ajax
Jamietelin
quelle
quelle
Antworten:
jQuery definiert jetzt eine when-Funktion für diesen Zweck.
Es akzeptiert eine beliebige Anzahl von verzögerten Objekten als Argumente und führt eine Funktion aus, wenn alle aufgelöst werden.
Das heißt, wenn Sie (zum Beispiel) vier Ajax-Anforderungen initiieren und dann eine Aktion ausführen möchten, wenn sie abgeschlossen sind, können Sie Folgendes tun:
Meiner Meinung nach sorgt dies für eine saubere und klare Syntax und vermeidet die Einbeziehung globaler Variablen wie ajaxStart und ajaxStop, die bei der Entwicklung Ihrer Seite unerwünschte Nebenwirkungen haben können.
Wenn Sie nicht im Voraus wissen, auf wie viele Ajax-Argumente Sie warten müssen (dh Sie möchten eine variable Anzahl von Argumenten verwenden), ist dies immer noch möglich, aber nur ein wenig schwieriger. Siehe Übergeben eines Arrays von Zurückgestellten an $ .when () (und möglicherweise jQuery .when Fehlerbehebung mit variabler Anzahl von Argumenten ).
Wenn Sie eine tiefere Kontrolle über die Fehlermodi der Ajax-Skripte usw. benötigen, können Sie das von zurückgegebene Objekt speichern
.when()
- es ist ein jQuery Promise- Objekt, das alle ursprünglichen Ajax-Abfragen umfasst. Sie können.then()
oder aufrufen.fail()
, um detaillierte Erfolgs- / Fehlerbehandlungsroutinen hinzuzufügen.quelle
$.when
einPromise
Objekt zurückgegeben wird, das nicht nur nützlichere Methoden hat.done
. Mit der.then(onSuccess, onFailure)
Methode können Sie beispielsweise reagieren, wenn beide Anforderungen erfolgreich sind oder mindestens eine fehlschlägt.fail
Fall. Im Gegensatz dazudone
scheiternfail
Brände sofort beim ersten Fehlschlag und ignorieren die verbleibenden Verzögerungen.onFailure
Funktion angehängt werden könnte. Wie ich in einem Kommentar zur Frage des OP betonte: Vielleicht möchte er genauer angeben, was er mit "erledigt" meinte. „Ryan Mohr“ hatte auch einen sehr guten Punkt in Bezug auf die Tatsache , dassfail
verhält sich anders alsdone
einige weitere Lesung getan werden überPromises
Ich denke , html5rocks.com/en/tutorials/es6/promisesWenn Sie wissen möchten, wann alle
ajax
Anforderungen in Ihrem Dokument abgeschlossen sind, egal wie viele davon vorhanden sind, verwenden Sie einfach das Ereignis $ .ajaxStop wie folgt :Update:
Wenn Sie sich an die
ES
Syntax halten möchten, können Sie Promise.all für bekannteajax
Methoden verwenden:Ein interessanter Punkt hier ist, dass es sowohl mit
Promises
als auch mit$.ajax
Anfragen funktioniert .Hier ist die jsFiddle- Demonstration.
Update 2:
Noch neuere Version mit asynchroner / wartender Syntax:
quelle
Ich fand eine gute Antwort von gnarf mein Selbst , das ist genau das , was ich gesucht :)
jQuery ajaxQueue
Anschließend können Sie der Warteschlange eine Ajax-Anforderung wie folgt hinzufügen:
quelle
Verwenden Sie das
ajaxStop
Ereignis.Angenommen, Sie haben beim Abrufen von 100 Ajax-Anforderungen eine Nachricht zum Laden ... und möchten diese Nachricht nach dem Laden ausblenden.
Aus dem jQuery- Dokument :
Beachten Sie, dass es darauf wartet, dass alle Ajax-Anforderungen auf dieser Seite ausgeführt werden.
quelle
HINWEIS: Die obigen Antworten verwenden Funktionen, die zum Zeitpunkt des Schreibens dieser Antwort noch nicht vorhanden waren. Ich empfehle die Verwendung
jQuery.when()
anstelle dieser Ansätze zu verwenden, aber ich lasse die Antwort für historische Zwecke.- -
Sie könnten wahrscheinlich mit einem einfachen Zählsemaphor auskommen, obwohl die Art und Weise, wie Sie es implementieren, von Ihrem Code abhängt. Ein einfaches Beispiel wäre so etwas wie ...
Wenn Sie möchten, dass dies wie {async: false} funktioniert, Sie den Browser jedoch nicht sperren möchten, können Sie dasselbe mit einer jQuery-Warteschlange erreichen.
quelle
.get()
. Auf diese Weise duplizieren Sie diesen Code zumindest nicht. Nicht nur das, sondern das Deklarieren einesfunction(){}
jedes Mal reserviert jedes Mal Speicher! Eher schlechte Praxis, wenn Sie eine statisch definierte Funktion aufrufen könnten.Javascript ist ereignisbasiert, daher sollten Sie niemals warten , sondern Hooks / Callbacks festlegen
Sie können wahrscheinlich nur die Erfolgs- / Vollständigkeitsmethoden von jquery.ajax verwenden
Oder Sie könnten .ajaxComplete verwenden :
obwohl Sie einen Pseudocode veröffentlichen sollten, wie Ihre Ajax-Anfrage (n) aufgerufen wird (werden), um genauer zu sein ...
quelle
Eine kleine Problemumgehung ist ungefähr so:
Hoffnung kann nützlich sein ...
quelle
Mit jQuery können Sie angeben, ob die Ajax-Anforderung asynchron sein soll oder nicht. Sie können die Ajax-Anforderungen einfach synchronisieren, und der Rest des Codes wird erst ausgeführt, wenn sie zurückgegeben werden.
Zum Beispiel:
quelle
Wenn Sie etwas Einfaches brauchen; einmal und Rückruf erledigt
quelle
Sie können auch async.js verwenden .
Ich denke, es ist besser als $ .wenn, weil Sie alle Arten von asynchronen Anrufen zusammenführen können, die keine sofort einsatzbereiten Versprechen wie Timeouts, SqlLite-Aufrufe usw. und nicht nur Ajax-Anforderungen unterstützen.
quelle
Auf der Grundlage der Antwort von @BBonifield habe ich eine Dienstprogrammfunktion geschrieben, damit die Semaphorlogik nicht in allen Ajax-Aufrufen verteilt wird.
untilAjax
ist die Dienstprogrammfunktion, die eine Rückruffunktion aufruft, wenn alle ajaxCalls abgeschlossen sind.ajaxObjs
ist ein Array von Ajax-Einstellungsobjekten[http://api.jquery.com/jQuery.ajax/]
.fn
ist RückruffunktionBeispiel:
doSomething
Funktion verwendetuntilAjax
.quelle
Ich empfehle dringend, $ .when () zu verwenden, wenn Sie bei Null anfangen.
Obwohl diese Frage über Millionen Antworten hat, fand ich für meinen Fall nichts Nützliches. Angenommen, Sie müssen sich mit einer vorhandenen Codebasis befassen, bereits einige Ajax-Aufrufe tätigen und möchten nicht die Komplexität von Versprechungen einführen und / oder das Ganze wiederholen.
Wir können leicht die Vorteile von jQuery nehmen
.data
,.on
und.trigger
Funktionen , die seit immer ein Teil von jQuery gewesen sein.Codepen
Das Gute an meiner Lösung ist:
Es ist offensichtlich, wovon der Rückruf genau abhängt
Der Funktion
triggerNowOrOnLoaded
ist es egal, ob die Daten bereits geladen wurden oder wir noch darauf wartenEs ist super einfach, es in einen vorhandenen Code einzufügen
quelle
Ich verwende die Größenprüfung, wenn alle Ajax-Ladevorgänge abgeschlossen sind
quelle
Um Alex 'Antwort zu erweitern, habe ich ein Beispiel mit variablen Argumenten und Versprechungen. Ich wollte Bilder über Ajax laden und sie auf der Seite anzeigen, nachdem sie alle geladen wurden.
Dazu habe ich Folgendes verwendet:
Aktualisiert für einzelne oder mehrere URLs: https://jsfiddle.net/euypj5w9/
quelle
Wie in anderen Antworten erwähnt, können Sie
ajaxStop()
warten, bis alle Ajax-Anforderungen abgeschlossen sind.Wenn Sie dies für eine bestimmte
ajax()
Anfrage tun möchten, können Sie am besten diecomplete()
Methode innerhalb der bestimmten Ajax-Anfrage verwenden:Aber, wenn Sie nur auf ein paar und bestimmte Ajax-Anfragen warten müssen? Verwenden Sie die wunderbaren Javascript- Versprechen , um zu warten, bis die Ajax, auf die Sie warten möchten, fertig sind. Ich habe ein kurzes, einfaches und lesbares Beispiel gemacht, um Ihnen zu zeigen, wie Versprechen mit Ajax funktionieren.
Bitte schauen Sie sich das nächste Beispiel an . Ich habe
setTimeout
das Beispiel immer klarer gemacht.quelle
Ich fand einen einfachen Weg, es mit
shift()
quelle
Meine Lösung lautet wie folgt
Hat ganz gut funktioniert. Ich habe viele verschiedene Möglichkeiten ausprobiert, aber ich fand, dass dies die einfachste und am besten wiederverwendbare ist. Ich hoffe es hilft
quelle
Schau dir meine Lösung an:
1. Fügen Sie diese Funktion (und Variable) in Ihre Javascript-Datei ein:
2. Erstellen Sie ein Array mit Ihren Anforderungen wie folgt:
3. Rückruffunktion erstellen:
4. Rufen Sie die Funktion runFunctionQueue mit den folgenden Parametern auf:
quelle
$.when
funktioniert bei mir nicht,callback(x)
anstattreturn x
wie hier beschrieben zu arbeiten: https://stackoverflow.com/a/13455253/10357604quelle
Versuchen Sie es auf diese Weise. Machen Sie eine Schleife innerhalb der Java-Skriptfunktion, um zu warten, bis der Ajax-Aufruf beendet ist.
quelle
setTimeout()
tut NICHTtake a sleep
. In diesem Fall blockieren Sie einfach alle Registerkarten, bis siedone
wahr werden.done
niemals der Fall sein wird, solange die while-Schleife noch läuft. Wenn die while-Schleife ausgeführt wird, kann die Ereignisschleife nicht fortgesetzt werden und führt daher niemals den Rückruf zum Ajax-Erfolg aus.