为啥即使我 .catch() Promise.all() 也会抛出异常?

Posted

技术标签:

【中文标题】为啥即使我 .catch() Promise.all() 也会抛出异常?【英文标题】:Why does Promise.all() throw an exception even if I .catch() it?为什么即使我 .catch() Promise.all() 也会抛出异常? 【发布时间】:2021-06-19 06:44:12 【问题描述】:

运行代码

Promise.all(new Promise((res, rej) => rej('Failure!')))
.catch(() => console.log("It's all okay."))

在 Node v12.19.0 中,将 It's all okay. 记录到控制台,但仍会引发异常。这是为什么?我会期待与我跑步时相同的行为

new Promise((res, rej) => rej('Failure!'))
.catch(() => console.log("It's all okay."))

这也会将It's all okay. 记录到控制台,但不会引发异常。

如何在 Promise.all() 中捕获拒绝?

完整的控制台输出:

> Promise.all(new Promise((res, rej) => rej('Failure!'))).catch(() => console.log("It's all okay."))
Promise  <pending> 
> It's all okay.
(node:2872) UnhandledPromiseRejectionWarning: Failure!
(node:2872) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 4)

> new Promise((res, rej) => rej('Failure!')).catch(() => console.log("It's all okay."))
Promise  <pending> 
> It's all okay.

【问题讨论】:

Promise.all() 的参数应该是一组承诺,而不是一个承诺。 Promise.all(ARRAY_OF_PROMISE_HERE) 谢谢。我认为Promise.all(promise1, promise2, ...) 应该工作的假设是错误的。但是为什么即使它不是一个数组,它也会触发拒绝? 也许使用.catch((err) =&gt; console.log(err)) 而不是说“没关系。”:-P 未处理的拒绝来自new Promise((res, rej) =&gt; rej('Failure!')),它没有在任何地方处理,而不是来自Promise.all()(您处理处理)。 【参考方案1】:

正如 Bergi 在 cmets 中指出的那样......

如果您在没有 catch 语句的情况下执行第一段代码(或实际打印您捕获的错误),您会看到发生了什么。

Promise.all(new Promise((res, rej) => rej('Failure!')))

返回:

Promise <rejected>: TypeError
Uncaught (in promise) Failure!
Uncaught (in promise) TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))
    at Function.all (<anonymous>)
    at <anonymous>:1:9

注意第一个错误是我们通过拒绝承诺而引发的错误。

第二个错误来自于没有正确使用Promise.all(),这是您遇到的错误。

由于Promise.all() 方法的错误使用,我们通过拒绝承诺引发的错误永远不会被捕获。


现在,让我们在数组中使用我们的 promise 测试代码,这是 Promise.all() 的正确用法,正如 cmets 中的 Barmar 所指出的那样。

Promise.all([new Promise((res, rej) => rej('Failure!'))])
    .catch(() => console.log("It's all okay."))

返回:

Promise <fulfilled>
It´s all okay.

所以,我们成功捕获了被拒绝的承诺错误。

另外值得注意的是,最终返回的promise是catch()方法执行后返回的promise。尽管Promise.all() 实际返回的promise 被拒绝了,但自从我们成功执行了catch 语句后,它就实现了。

【讨论】:

以上是关于为啥即使我 .catch() Promise.all() 也会抛出异常?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我必须使用 try/catch [重复]

为啥我不能在 Promise.catch 处理程序中抛出?

为啥 .catch() 没有做任何事情?

即使代码在try / catch块中,我仍然会收到异常[关闭]

即使代码在 try/catch 块中,我也会不断收到异常 [关闭]

为啥在 Try ... Catch 中使用 finally