是否有可能在Promise.all中捕获所有被拒绝的承诺?

时间:2016-11-28 18:54:28

标签: javascript ecmascript-6 es6-promise

鉴于以下内容

Promise.all(promises).then(resolved => {
    ...
}).catch(rejected => {
    ...
});

rejected只会包含被拒绝的第一个承诺。有没有办法捕获被拒绝的所有承诺?

2 个答案:

答案 0 :(得分:14)

当然,这样做需要等到所有输入承诺都已解决。只要有一个待处理,可能会拒绝,你就无法确定是否有所有拒绝!

所以你可以使用Promise.all,但是在转换输入promises以便捕获拒绝并识别它们之后,可能将它们包装在Error对象中,如

caughtPromises = promises.map(promise => promise.catch(Error));

现在过滤Promise.all的结果,找到被识别为失败的结果:

Promise.all(caughtPromises)
  .then(results => results.filter(result => result instanceof Error))

etvoilà。

答案 1 :(得分:1)

等待所有承诺得到解决(解决或拒绝)的通常方法是使用Promise.settle()之类的东西。您可以在此处查看其中的几种不同变体:ES6 Promise.all() error handle - Is .settle() needed?

基本概念是你用一个包装器来包装每个你的承诺,这个包装器捕获(并保存)它们的拒绝并将它们变成结果,然后你将这些承诺传递给Promise.all()。由于您传递给Promise.all()的所有承诺都将解决(没有人会拒绝),它将等待所有这些承诺。但是,结果值将是一个数组,您可以迭代以查看哪些承诺已解决,哪些承诺被拒绝:

你会让他们这样使用它:

Promise.settle(arrayOfPromises).then(function(results) {
    results.forEach(function(pi, index) {
        if (pi.isFulfilled()) {
            console.log("p[" + index + "] is fulfilled with value = ", pi.value());
        } else {
            console.log("p[" + index + "] is rejected with reason = ", pi.reason());
        }
    });
});

请参阅上面关于Promise.settle()的实际代码的链接发布,以避免在此处重复。