2017-09-13 4 views
-2

Ich habe dieses Beispiel aus der Axios AJAX-Bibliothek genommen, aber das gleiche gilt für Promises.all().Promises.all wie sicherzustellen, dass alle Versprechen haben, sind verfügbar?

Bisher habe ich gelesen, Sie können Promises.all() verwenden, um zu überprüfen, ob alle Versprechen aus einer Reihe von Versprechen gelöst worden sind.

Das ist wirklich ordentlich, aber was passiert, wenn Sie ein Versprechen setzen und es verrechnet, bevor das nächste geschoben wurde?

Ich rate mit dem Overhead von meinem durchschnittlichen AJAX-Aufruf von mindestens 50ms der Push wird immer passieren, bevor irgendwelche Ajax-Anfragen, aber nur sagen, dafür genommen gewährt nicht wirklich richtig.

Es gibt zwei Lösungen für diese, die ich denken konnte:

  1. eine Zählung Verwenden Sie beide, um sicherzustellen, (in thise Fall) AJAX-Anforderungen sind in der
    Array.

  2. Überprüfen Sie, ob die tatsächlichen Funktionsnamen vorhanden sind.

Wie sind andere Umgang mit diesem oder sind die meisten Menschen einfach zufrieden mit der Hoffnung auf beiden AJAX Anfragen geschoben wird, bevor ein einzelner kann man schnell genug gelöst werden.

axios.all([getUserAccount(), getUserPermissions()]) 
    .then(axios.spread(function (acct, perms) { 
    // Both requests are now complete 
    })); 
+0

Es ist nicht sehr klar, was Sie fragen. Entwickeln Sie dynamisch die Palette der Versprechen? Oder wundern Sie sich, ob die Anfragen irgendwie enden, bevor sie verpackt sind? – Nit

+0

Ja, diese Versprechen werden von mehreren Orten aus gedrängt. Nehmen wir an, ein einzelnes Versprechen wurde gedrängt, während ich zwei Versprechen erwarten würde, dann könnte theoretisch dieses eine Versprechen einen dann auslösen, bevor der zweite gedrängt wurde? Wenn das der Fall ist, muss es einen Mechanismus geben, um dies vorher zu prüfen, nein? –

+0

Sie benötigen keinen Mechanismus, um dies vorher zu überprüfen. 'Promise.all' macht aus einer Reihe von Versprechen ein Versprechen. Wie meinst du, sie werden von verschiedenen Orten geschoben –

Antwort

1

Sie müssen sich keine Sorgen über Versprechen machen, die aufgelöst werden, bevor sie an Promise.all übergeben werden: Promise.all wird nicht aufgerufen, bevor sein Argument (Array) vollständig ausgewertet wurde. Nur wenn das Array bereit ist, wird Promise.all aufgerufen.

Ob eines dieser Versprechen bereits gelöst ist, zu der Zeit Promise.all genannt wird, ist wirklich nicht wichtig. Promise.all prüft, welche in einem aufgelösten Zustand sind und ruft nur seine then Methode auf, wenn alle von ihnen erfüllt worden sind. Es könnte sogar sein, dass alle die Versprechen im Array bereits erfüllt sind: kein Problem, sobald Promise.all ausgeführt wird, wird es die Ausführung der then-Methode planen. Selbst die Zeit, in der diese Versprechen bereits gelöst waren, spielt keine Rolle. Selbst wenn sie vor einer Stunde gelöst wurden, wird Promise.all ihre Aufgabe immer noch korrekt erledigen.

+0

Ich möchte nicht überprüfen, ob das Versprechen gelöst wurde, da diese Information innerhalb des Versprechens enthalten ist und 'Promise.all()' wird dies für mich überprüfen. Ich möchte sicherstellen, dass 'Promises.all()' nicht ausgelöst wird, wenn ich nicht alle Versprechen in meinem Array, die ich möchte, übertragen habe. Aber nach der Antwort von @fatman wird die 'sync'-Operation eines' push' immer stattfinden, bevor irgendeine 'async' Anfrage ausgelöst wird. Also denke ich, das ist kein Problem mehr. Vielen Dank für Ihren Einblick, schätzen Sie es. –

+1

Ihr Array wird abgeschlossen, wenn Sie es an 'Promise.all' übergeben. Mein Punkt ist, dass es keine Möglichkeit gibt, ein unvollständiges Array an "Promise.all" zu übergeben (außer Sie tun dies natürlich absichtlich und modifizieren das Array * nach dem * Aufruf von 'Promise.all'). JavaScript wertet das Argument immer zuerst aus, bevor es die Funktion aufruft, an die das Argument übergeben wird. – trincot

+0

Eigentlich ist diese Antwort die richtige – Tomer

0

Axios.all calls Promise.all, die eine einzige Zusage zurückgibt, die löst, wenn alle Versprechungen im iterable Argument sind aufgelöst.

Axios.spread werden die aufgelösten Werte von getUserAccount und getUserPermission erhalten.

0

Push ist eine Synchronisierungsoperation, Ajax ist asynchron. JS wird immer alle Synchronisierungsoperationen ausführen, bevor eine asynchrone Operation ausgeführt wird, selbst wenn sie bereits beendet wurde. Zum Beispiel:

for (i=0;i<10000000;i++){ 
    console.log('looping'); 
} 

setTimeout(function(){ 
    console.log('running async') 
}, 0) 

Obwohl die Timeout auf 0 gesetzt ist, so kann sie sofort ausführen, wird es warten, bis die für die Schleife und erst dann erfolgt die Async-Betrieb laufen.

Also selbst wenn Sie ein Versprechen und es sofort verrechnet, wird es warten, bis der Push erledigt ist und nur dann wird auf die gelösten Versprechen reagieren.

+0

Wow, ich werde das ausprobieren und darüber nachlesen. Wenn dies zutrifft, ist 'Promises.all()' eine brillante Lösung für den Umgang mit mehreren AJAX-Anfragen. Goldene Antwort genau dort. –

+1

Obwohl die Erklärung von async und sync korrekt ist, ist dies nicht der Grund, warum ein 'push' zuerst ausgewertet wird: Es ist, weil dies die richtige Reihenfolge der Auswertung in JavaScript ist: Ein Argument (Array in diesem Fall) muss zuerst vollständig sein ausgewertet vor der Funktion (an die dieses Argument übergeben wird, dh 'Promise.all') wird ausgeführt (auch synchron). Das hat also wenig mit asynchronem Code zu tun. – trincot

Verwandte Themen