2017-11-26 3 views
0

Ich versuche, eine for-Schleife auszuführen, die eine Reihe asynchroner Anforderungen in die Warteschlange stellt. Sobald alle Anfragen abgeschlossen sind, unabhängig davon, ob sie resolve oder reject sind, möchte ich dann etwas Code ausführen. Ich versuche, das Async/Abwarten-Muster zu nutzen, da es schöner aussieht. :)So ignorieren Sie Fehler mithilfe der Syntax async/await in JavaScript Promise.all()

Das ist, was ich tue:

var promises = [] 
for (item in list) { 
    prom = AsyncFunction(item) 
    promises.push(prom) 
} 

await Promise.all(promises) 

doMoreAfter() 

Allerdings scheitern einige der Versprechungen, und die zweite, die Promise.all() ausfällt als gut passiert.

Ich möchte einfach alle fehlgeschlagenen Versprechen ignorieren und den nächsten Code ausführen, nachdem alle Versprechen abgeschlossen sind.

Ich fand Lösungen wie this.

Promise.all([a(), b(), c()].map(p => p.catch(e => e))) 
    .then(results => console.log(results)) // 1,Error: 2,3 
    .catch(e => console.log(e)); 

Aber es sieht nicht aus wie es funktioniert, wenn Sie versuchen, es in das async/abwarten-Format zu verwandeln.

await Promise.all(promises.map(p => p.catch(e => e))) 

Was fehlt mir?

+0

Nun, 'Promise.all()' verwirft, sobald das erste Versprechen Sie es passieren lehnt so dass der einzige Weg, es zu machen warten Für alle Versprechen zu beenden ist, jedes Versprechen, das du an "Promise.all()" übergibst, davon abzuhalten. Wenn ich diese Art von Verhalten möchte, verwende ich einfach eine dieser [Promise.settle() 'Versionen] (https://stackoverflow.com/questions/36605253/es6-promise-all-error-handle-is-setle -needed/36605453 # 36605453), die Ihnen das gewünschte Verhalten bietet, das in eine Dienstprogrammfunktion integriert ist, anstatt jedes Mal einzeln manuell zu codieren. – jfriend00

Antwort

3

I wie das beste Gefühl, die Sie tun können, ist dies:

var promises = [a, b, c]; 
promises = promises.map(p => p().catch(e => undefined)); 

values = await Promise.all(promises); 
console.log(values); // ["a", undefined, "c"] 

https://jsfiddle.net/DerekL/h5Lmxaqq/

Oder Sie können eine ignore Funktion erstellen:

function ignore(promise){ 
    return promise.catch(e => undefined); 
} 

async function main(){ 
    var promises = [a(), b(), c()]; 

    var values = await Promise.all(promises.map(ignore)); 
    console.log(values); 
} 

https://jsfiddle.net/DerekL/mwkww7w9/

+0

Danke. Im Allgemeinen scheint es beim Umgang mit Mehrfachversprechen in einer Schleife nicht so gut zu sein, dass man auf "erwarten/asynchron" setzt. Beispielsweise wird der von der Async-Funktion zurückgegebene Wert angezeigt, sobald er zurückkehrt. 'awaward' blockiert die Schleife, aber' .then() 'nicht. Ist das ein richtiges Verständnis für den aktuellen Stand der Dinge? Vielleicht sollte ich einfach die async/await-Syntax für dieses spezielle Problem vermeiden ... –

+0

Die 'async/await'-Syntax funktioniert gut mit' Promise.all', aber Ihr Fall ist ein bisschen speziell und die Arbeit mit rohen Versprechen ist wahrscheinlich eine bessere Idee. –

+0

In Ihrem letzten Beispiel, können Sie nicht einfach 'var values ​​= warten auf Promise.all (provents.map (ignore));'? – jfriend00

0

Ich versuchte, läuft Ihr Beispiel wie folgt: https://jsfiddle.net/804ogadu/3/

var a = Promise.resolve('a'); 
var b = Promise.resolve('b') 
var c = Promise.reject('errc'); 

async function test(){ 
const t = await Promise.all([a, b, c].map(p => p.catch(e => e))); 
console.log(t); 
} 

test(); 

ich tun das gewünschte Ergebnis

['a,'b','errc'] 
Verwandte Themen