gpt4 book ai didi

javascript - 为什么我会通过 await Promise.all 收到未处理的 Promise Rejection

转载 作者:行者123 更新时间:2023-12-04 16:37:33 28 4
gpt4 key购买 nike

这是我的代码的一般结构:

(async () => {
try {
const asyncActions = []

for (let i = 0; i < 3; i++) {
await new Promise((resolve, reject) => setTimeout(resolve, 1000))

for (let j = 0; j < 3; j++) {
asyncActions.push(new Promise((resolve, reject) => setTimeout(reject, 1000)))
}
}

await Promise.all(asyncActions)
console.log('all resolved')
}
catch (e) {
console.log('caught error', e)
}
})()
我希望这能捕捉到 asyncActions 中发生的任何拒绝。因为它们应该由 Promise.all() 处理,但不知何故他们没有处理?控制台显示以下内容:
(node:9460) UnhandledPromiseRejectionWarning: undefined
(Use `node --trace-warnings ...` to show where the warning was created)
(node:9460) 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: 1)
(node:9460) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:9460) UnhandledPromiseRejectionWarning: undefined
(node:9460) 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: 2)
...

(node:9460) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
(node:9460) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 2)
...
为什么不被 Promise.all() 处理然后被捕获 block 捕获?
我还注意到,当我同时更换 new Promise(...)只需 Promise.resolve()Promise.reject()它分别捕获错误。这是为什么?两种变体不是异步的,因此应该以相同的方式工作吗?

最佳答案

我们在 Node.js 中检测未处理 promise 拒绝的方式是使用启发式。
当一个 Promise 被拒绝时,我们给用户一个仍然附加监听器(同步)的机会——如果他们不这样做,我们假设它没有被处理并导致 unhandledRejection .这是因为:

  • 不可能(如在停止问题中)知道用户将来是否会附加这样的处理程序。
  • 在绝大多数情况下,它就足够了,因为最好的做法是始终立即附加监听器。

  • 所以 - 您需要始终同步添加 catch 监听器,以避免未处理的拒绝。
    您也可以(在非人为的情况下)通过在 fork 中添加一个空的 catch 监听器来选择退出:
    (async () => {
    try {
    const asyncActions = []

    for (let i = 0; i < 3; i++) {
    await new Promise((resolve, reject) => setTimeout(resolve, 1000))

    for (let j = 0; j < 3; j++) {
    const p = new Promise((resolve, reject) => setTimeout(reject, 1000));
    p.catch(() => {}); // suppress unhandled rejection
    asyncActions.push(p)
    }
    }

    await Promise.all(asyncActions)
    console.log('all fulfilled')
    }
    catch (e) {
    console.log('caught error', e)
    }
    })()
  • 有趣的历史花絮 #1:我们考虑使用 GC 来检测 unhandledRejections - 人们发现它更令人困惑。
  • 有趣的历史花絮 #2:Chrome 做了同样的事情,但如果你添加一个监听器,实际上会追溯删除消息。
  • 有趣的历史花絮#3:这个启发式起源于 2013 年的 bluebird 。我 talk about it here .
  • 关于javascript - 为什么我会通过 await Promise.all 收到未处理的 Promise Rejection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67789309/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com