2014-09-12 5 views
29

Jemand brachte heute einen interessanten Fall mit Bluebird, was ist der beste Weg, um mehrere Versprechen zu behandeln, wo wir nicht daran interessiert sind, auf eine bestimmte Erfüllung oder Ablehnung zu stoppen, sondern interessiert an der Überprüfung des Endergebnisses. Ein Beispiel:Bluebird Promise.all - mehrere Versprechen abgeschlossen aggregieren Erfolg und Ablehnungen

var p1 = new Promise(function(f,r){ 
    setTimeout(function(){ 
     console.log("p1"); 
     f("yay"); 
    }, 100); 

}); 

var p2 = new Promise(function(f,r){ 
    setTimeout(function(){ 
     console.log("p2"); 
     r(new Error("boo")); 
    }, 200); 

}) 

var p3 = new Promise(function(f,r){ 
    setTimeout(function(){ 
     console.log("p3"); 
     r(new Error("yay")); 
    }, 300); 

}); 

var p4 = new Promise(function(f,r){ 
    setTimeout(function(){ 
     console.log("p4"); 
     f("yay"); 
    }, 400); 

}); 


//Promise.all([p1,p2, p3, p4]).then(function(p){ 
// console.log("Results:",p); 
//}).error(function(e){ 
// console.log("Error:",e); 
//}); 

Promise.map([p1,p2, p3, p4],function(p){ 
    console.log("results:",p); 
}, {concurrency:10}).error(function(e){ 
    console.log("Error:",e); 
}); 

Wenn hier laufen wir entweder Karte oder alle abgelehnt Versprechungen verursacht Handler nicht Ergebnisse zu berichten.

Zum Beispiel die Ergebnisse der laufenden Promise.map, wie oben ausgeführt ist:

debugger listening on port 65222 
p1 
results: yay 
p2 
Error: [Error: boo] 
p3 
p4 

Process finished with exit code 0 

Hier ist der Code für jedes Versprechen führt, aber nur 1 Ergebnis und 1 Fehler gemeldet. Der Fehler führt dazu, dass der Prozess gestoppt wird.

Wenn wir alle auskommentieren, erhalten wir ein ähnliches Verhalten. Diesmal wird nur der Fehler gemeldet. Irgendwelche Erfolge machen es dann (verständlicherweise) nicht möglich.

debugger listening on port 65313 
p1 
p2 
Error: [Error: boo] 
p3 
p4 

Process finished with exit code 0 

dieses Verhalten Anbetracht dessen, was der beste Weg, um alle Versprechen gehen würde, wo ein Szenario über die Implementierung sind ausgeführt und die Ergebnisse der erfüllten Versprechungen sind mit jedem und allen Ablehnungen berichtet?

Etwas wie:

Promise.aggregate([p1,p2,p3,p4]).then(function(fulfilled, rejected){ 
    console.log(fulfilled); //all success 
    console.log(rejected); //any and all rejections/exceptions 
}); 

Antwort

34

Sie würden .reflect verwenden:

Promise.all([p1,p2,p3,p4].map(x => x.reflect()).then(results => { 
    results.forEach(result => { 
    if(result.isFulfilled()){ 
     // access result.value() 
    } else { 
     // access result.reason() 
    } 
    }); 
}); 

Diese verwendet, um mit einer settle Funktion behandelt werden, die das traditionell für einen Array tat - es durch .reflect verallgemeinert wurde seit Es trennt Aggregation von der Vorstellung einer Verheißungsinspektion und lässt Sie tun, was .settle tat, aber auch zu anderen Aktionen wie .any oder .some.

+1

Ich glaube nicht, dass .setle von bluebird unterstützt wird, es gibt keine Erwähnung in ihren Dokumenten. – silverlight513

+2

@ silverlight513 ja Entschuldigung, wir haben es abgesetzt - es wird trotzdem funktionieren. Der Weg nach vorne ist die Verwendung von '.reflect'. Vielen Dank, dass Sie mich darauf aufmerksam gemacht haben. Ich werde die Antwort aktualisieren. –

+0

danke für die Aktualisierung – j03m