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

Is it possible to catch all rejected promises in Promise.all?

鉴于以下情况

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

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

当然,这样做需要等到所有的输入承诺都已结算。只要有一个处于待处理状态,它可能会被拒绝,您不能确定您已收到所有拒绝!

因此您可以使用 Promise.all,但在转换输入承诺之后,以便捕获拒绝并识别它们,也许通过将它们包装在 Error 对象中,如

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

现在过滤 Promise.all 的结果以找到标识为失败的结果:

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

瞧瞧。

等待所有承诺被解决(解决或拒绝)的通常方法是使用类似 Promise.settle() 的方法。您可以在这里看到它的几个不同变体:

基本概念是用包装器包装每个 promise,该包装器捕获(并保存)它们的拒绝并将它们转化为 resolves,然后将这些结果 promise 传递给 Promise.all()。由于您传递给 Promise.all() 的所有承诺都将解决(none 将拒绝),因此它将等待所有承诺。但是,结果值将是一个数组,您可以遍历该数组以查看哪些承诺已解决,哪些已拒绝:

你会让他们这样使用它:

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() 的实际代码,以避免在此处重复。