Bluebird Promise.all-多个承诺完成了成功和拒绝的汇总

Bluebird Promise.all - multiple promises completed aggregating success and rejections

本文关键字:成功 拒绝 all- Promise 承诺 Bluebird      更新时间:2023-09-26

今天有人向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);
});

在这里,如果我们运行映射或所有被拒绝的承诺,将导致处理程序不报告结果。

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

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

这里执行每个promise的代码,但只报告了一个结果和一个错误。该错误导致进程停止。

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

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概括,因为它将聚合与承诺检查的概念分离,并允许您执行.settle所做的操作,但也可以执行.any.some等其他操作。