今天有人与bluebird提出了一个有趣的案例,这是处理多重承诺的最佳方法,即我们对停止履行既定的目标或拒绝不感兴趣,而对检查最终结果感兴趣。一个例子:
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
此处执行每个promise的代码,但仅报告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:
.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,因为它从一个承诺检查的概念分离聚合,让你做什么.settle没有,但像其他操作.any或.some为好。
settle
.settle
.any
.some