是否有可能在 Promise.all 中捕获所有被拒绝的承诺? [复制]
Posted
技术标签:
【中文标题】是否有可能在 Promise.all 中捕获所有被拒绝的承诺? [复制]【英文标题】:Is it possible to catch all rejected promises in Promise.all? [duplicate] 【发布时间】:2017-04-12 14:20:23 【问题描述】:鉴于以下
Promise.all(promises).then(resolved =>
...
).catch(rejected =>
...
);
rejected
只会包含第一个被拒绝的承诺。有没有办法捕获所有被拒绝的承诺?
【问题讨论】:
个别来说,是的,但不是 .all。正如您所发现的,第一个被拒绝的承诺抛出了问题;它不会等待他们全部完成。您将不得不遍历每个 promise 并将 catch 处理程序附加到每个 promise,然后以某种方式确定它们何时全部完成(因为 .all 在那时将毫无用处)rejected
不会包含第一个被拒绝的承诺——它将包含它被拒绝的原因。
另请参阅this question,了解如何使用 Bluebird 治疗这种情况。检查使事情变得更容易。
@naomik 我猜你可以保留你的答案,尽管它会归结为重写它,基于 Promise.settle
或 like this 的 reconcile
。您可以保留第一部分中的示例,以及“这有何不同”部分。
【参考方案1】:
当然,这样做需要等到所有输入承诺都已解决。只要有一个待处理的,可能会被拒绝,你就不能确定你有所有的拒绝!
所以你可以使用Promise.all
,但在转换输入承诺之后,以便捕获拒绝并识别它们,也许通过将它们包装在Error
对象中,如
caughtPromises = promises.map(promise => promise.catch(Error));
现在过滤Promise.all
的结果以查找被标识为失败的结果:
Promise.all(caughtPromises)
.then(results => results.filter(result => result instanceof Error))
等等。
【讨论】:
【参考方案2】:等待所有承诺得到解决(解决或拒绝)的通常方法是使用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()
的实际代码,以避免在此处重复。
【讨论】:
和Promise.allsettled()
一样吗?
@MihaeKheel - 是的,类似。在任何现代 JS 环境中,您都可以使用内置的 Promise.allSettled()
。以上是关于是否有可能在 Promise.all 中捕获所有被拒绝的承诺? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
在 Javascript 中捕获 Promise.all() 的解决方案