Ich habe Code, der in Javascript ungefähr so aussieht:
forloop {
//async call, returns an array to its callback
}
Nachdem ALLE diese asynchronen Aufrufe abgeschlossen sind, möchte ich die min über alle Arrays berechnen.
Wie kann ich auf alle warten?
Meine einzige Idee im Moment ist es, ein Array von Booleschen Werten namens done zu haben und done [i] in der i-ten Rückruffunktion auf true zu setzen und dann while (nicht alle sind erledigt) {} zu sagen
edit: Ich nehme an, eine mögliche, aber hässliche Lösung wäre, das erledigte Array in jedem Rückruf zu bearbeiten und dann eine Methode aufzurufen, wenn alle anderen erledigten von jedem Rückruf festgelegt sind. Daher ruft der letzte abgeschlossene Rückruf die fortlaufende Methode auf.
Danke im Voraus.
javascript
asynchronous
Codierer sind Menschen
quelle
quelle
while (not all are done) { }
würde nicht funktionieren. Während Sie warten, kann keiner Ihrer Rückrufe ausgeführt werden.Antworten:
Sie waren mit Ihrem Code nicht sehr spezifisch, daher werde ich ein Szenario erstellen. Angenommen, Sie haben 10 Ajax-Anrufe und möchten die Ergebnisse dieser 10 Ajax-Anrufe sammeln. Wenn alle abgeschlossen sind, möchten Sie etwas unternehmen. Sie können dies so tun, indem Sie die Daten in einem Array sammeln und nachverfolgen, wann der letzte fertig ist:
Manueller Zähler
Hinweis: Die Fehlerbehandlung ist hier wichtig (wird nicht angezeigt, da sie sich darauf bezieht, wie Sie Ihre Ajax-Anrufe tätigen). Sie sollten sich überlegen, wie Sie mit dem Fall umgehen sollen, wenn ein Ajax-Aufruf nie abgeschlossen wird, entweder mit einem Fehler oder wenn er für eine lange Zeit stecken bleibt oder nach einer langen Zeit eine Zeitüberschreitung aufweist.
jQuery verspricht
Zu meiner Antwort im Jahr 2014 hinzufügen. Heutzutage werden Versprechen häufig verwendet, um diese Art von Problem zu lösen, da jQuery
$.ajax()
bereits ein Versprechen zurückgibt und$.when()
Sie darüber informiert, wenn eine Gruppe von Versprechen alle gelöst sind, und die Rückgabeergebnisse für Sie sammelt:ES6-Standardversprechen
Wie in der Antwort von kba angegeben : Wenn Sie eine Umgebung mit integrierten nativen Versprechungen haben (moderner Browser oder node.js oder Verwendung von babeljs transpile oder Verwendung einer Versprechen-Polyfüllung), können Sie ES6-spezifizierte Versprechungen verwenden. In dieser Tabelle finden Sie Informationen zur Browserunterstützung. Versprechen werden in nahezu allen aktuellen Browsern mit Ausnahme des IE unterstützt.
Wenn
doAjax()
ein Versprechen zurückgegeben wird, können Sie dies tun:Wenn Sie eine asynchrone Operation ohne Versprechen in eine Operation verwandeln müssen, die ein Versprechen zurückgibt, können Sie sie wie folgt "versprechen":
Und dann verwenden Sie das obige Muster:
Bluebird verspricht
Wenn Sie eine funktionsreichere Bibliothek wie die Bluebird-Versprechensbibliothek verwenden , sind einige zusätzliche Funktionen integriert, um dies zu vereinfachen:
quelle
doAjax()
, die ein Versprechen als eine der Optionen zurückgibt. Das Gleiche wiefetch()
.Einchecken ab 2015: Wir haben jetzt native Versprechen in den neuesten Browsern (Edge 12, Firefox 40, Chrome 43, Safari 8, Opera 32 und Android Browser 4.4.4 und iOS Safari 8.4, jedoch nicht in Internet Explorer, Opera Mini und älteren Versionen von Android).
Wenn wir 10 asynchrone Aktionen ausführen und benachrichtigt werden möchten, wenn alle abgeschlossen sind, können wir die native Aktion
Promise.all
ohne externe Bibliotheken verwenden:quelle
Promises.all()
sollte seinPromise.all()
.Promise.all()
in denen keine aktuellen IE-Versionen enthalten sind.Sie können jQuery verwenden latentes mit der entlangen Objekt , wenn Methode.
quelle
jQuery
was normalerweise bedeutet, dass das OP keine jQuery-Antwort wollte.Sie können es folgendermaßen emulieren:
dann führt jeder asynchrone Aufruf Folgendes aus:
Während Sie bei jedem asynchronen Rückruf am Ende der Methode diese Zeile hinzufügen:
Mit anderen Worten, Sie emulieren eine Countdown-Latch-Funktion.
quelle
Dies ist meiner Meinung nach der ordentlichste Weg.
Promise.all
FetchAPI
(Aus irgendeinem Grund funktioniert Array.map nicht in .then-Funktionen für mich. Sie können jedoch .forEach und [] .concat () oder ähnliches verwenden.)
quelle
return responses.map(response => { return response.json(); })
, oderreturn responses.map(response => response.json())
.Verwenden Sie eine Kontrollflussbibliothek wie
after
quelle