2017-01-03 2 views
0

Ich habe zwei Versprechen, unabhängig voneinander und ich möchte einen endgültigen Schritt nach machen beide Versprechen sind abgeschlossen (entweder ablehnt oder löst).Wie kann man single finally handler für mehrere Versprechen in AngularJS haben?

$ q.all() kann nicht verwendet werden, da ich die schließlich wollen immer (für beide Versprechen nur einmal) ausgeführt werden, selbst wenn eine der Versprechungen

Eine Lösung weist einen Zähler haben könnte und haben eine finallyHandler-Funktion, um es auszuführen, wenn beide Versprechen verfallen/zurückgewiesen werden.

var count = 0; 
    function finallyHandler() { 
    if (++count === 2) { 
     doStuff(); 
     count = 0; 
     } 
    } 

firstPromise.finally(finallyHandler); 
secondPromise.finally(finallyHandler); 

Diese Arbeit kann aber nicht richtig aus.

Gibt es einen besseren Weg, dies zu tun?

+1

Was ist mit einem dritten Versprechen, das löst, wenn beide entweder gelöst oder zurückgewiesen? Es würde den Code leichter zu lesen und zu halten machen. – briosheje

+0

@briosheje hat die richtige Idee. Erstellen Sie das Array von Versprechen, so dass jedes sein eigenes pass-through Fehlerverhalten hat. 'Versprechungen.Push (doStuff(). catch (e => e))', dann wenden Promise.all auf 'Versprechen' – danh

Antwort

0

Normalerweise $q.all löst auf das erste Versprechen abgelehnt, das abgelehnt wird und nicht auf die anderen Versprechen wartet. Um alle zu warten versprechen entweder erfüllt oder abgelehnt, machen resiliant Versionen jedes Versprechen zu lösen, dann $q.all auf diejenigen verwenden:

var resiliantFirstPromise = firstPromise.catch(e => "CONVERTED"); 
var resiliantSecondPromise = secondPromise.catch(e => "CONVERTED"); 

$q.all([resiliantFirstPromise, resiliantSecondPromise]) 
    .then(() => { 
    console.log("Both promises have resolved"); 
}); 

Durch einen Wert an die .catch Methode zurückkehrt, jedes Versprechen, das abgelehnt wird, liefert eine abgeleitete Versprechen das wurde in ein erfülltes Versprechen umgewandelt. Da keine der abgeleiteten Versprechen abgelehnt wird, wartet die $q.all auf beide Versprechen gelöst (entweder erfüllt oder abgelehnt).

+0

Das sieht gut aus und funktioniert gut! Ich war verwirrt mit beiden Versprechungen, um gelöst zu werden, Teil, denn ** Entschlossenheit ** bedeutet oft ** erfüllt **. Es wäre also eine bessere Idee, es in "... zu ändern (entweder erfüllt oder abgelehnt)" zu ändern. – Hemant

+0

Während ich stimme einigen Leuten zu, die * gelöst * * * gelöst * *, die [Promises/A + Spec] (https : //promisesaplus.com/) verwendet den Begriff "Auflösung", um die Änderung vom Status "ausstehend" in "erfüllt" oder "abgelehnt" zu ändern. Ich bleibe lieber bei dieser Terminologie als ein neues Wort einzuführen. Siehe [Promises/A + Das Promise Resolution-Verfahren] (https://promisesaplus.com/#point-45). – georgeawg

0
firstPromise().catch().secondPromise().catch().then(//what you want) 

Die oben genannte Versprechenkette kann dies erreichen. Endgültige then würde in allen Szenarien aufgerufen werden. catch würde die Versprechen Ablehnungen propagieren.

+0

Sieht so aus, als hätte ich die Frage nicht korrekt gestellt. Das 'finally' sollte nur aufgerufen werden, wenn beide Versprechen gemacht wurden (ablehnen oder auflösen). Ich möchte auf alle Versprechen warten. Das wird also nicht richtig funktionieren. – Hemant

+0

aktualisiert die Antwort – raj

1

Promise.all (iterable) wird tun, was Sie suchen. Bitte beachten Sie jedoch die Browserkompatibilität, da Internet Explorer diese Methode NICHT unterstützt. Aus der Dokumentation:

Die Promise.all (abzählbaren) Methode gibt ein Versprechen, dass, wenn all den Versprechungen im iterable Argument löst haben beschlossen, oder lehnt mit dem Grund des ersten Versprechen übergeben, die ablehnt.

Ihr Codebeispiel verwenden (mit Ausfallverhalten), wäre es wie folgt aussehen:

Promise.all([firstPromise, secondPromise]).then(values => { 
    finallyHandler(); 
}, reason => { 
    finallyHandler(); 
}); 

Auch wenn der Fehler Block der gleiche wie der Erfolg Block ist, wird nur der Erfolg Block wird einmal alle Versprechen erfolgreich abgeschlossen wurde und die Fehlerblockierung einmal (und nur einmal) ausgeführt wird, wird der erste Fehler festgestellt.

Referenz:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

Verwandte Themen