蓝鸟Promise.all – 多个承诺完成聚合成功和拒绝

今天有人用蓝鸟提出一个有趣的案例,处理多重承诺的最佳方式是什么,我们不想停止某个履行或拒绝,而是对检查最终结果感兴趣。 一个例子:

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); }); 

在这里,如果我们运行map或所有被拒绝的promise都会导致处理程序不报告结果。

例如上面实现的运行Promise.map的结果是:

 debugger listening on port 65222 p1 results: yay p2 Error: [Error: boo] p3 p4 Process finished with exit code 0 

在这里执行每个承诺的代码,但只有1个结果和1个错误被报告。 错误导致进程停止。

如果我们取消注释,我们会得到类似的行为。 这次只报告错误。 任何成功都不会成为(可以理解)。

 debugger listening on port 65313 p1 p2 Error: [Error: boo] p3 p4 Process finished with exit code 0 

考虑到这种行为,最好的办法是实施一个场景,在这个场景下,所有的承诺都会被运行,而履行的承诺的结果会被任何和所有的拒绝报告。

就像是:

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

你会使用.reflect

 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() } }); }); 

这个过去常常被一个settle函数处理,这个函数在传统的数组中是这样做的 – 它被.reflect泛化,因为它将聚合与promise检查的概念分离开来,并且让你做一些其他动作,比如.any.some有一些。