2014-09-12 116 views
29

有人提出了一个有趣的案例今天与蓝鸟,处理多个承诺的最佳方式,我们不想停止给定履行或拒绝,而是宁愿有兴趣检查最终结果。举例:Bluebird 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 
}); 

回答

34

你会使用.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因为广义它将聚合与承诺检查的概念分开,并让您执行​​所做的操作,但也可以执行其他操作,如.any.some

+1

我不认为.settle被蓝鸟支持了,在他们的文档中没有提及它。 – silverlight513 2016-03-09 11:02:27

+2

@ silverlight513对不起,我们不推荐定居 - 它仍然可以工作。前进的方向是使用'.reflect'。感谢您提醒我注意我会更新答案。 – 2016-03-09 11:09:19

+0

感谢您的更新 – j03m 2016-06-20 13:44:00