这是我的代码的一般结构:
(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)
}
})()
关于javascript - 为什么我会通过 await Promise.all 收到未处理的 Promise Rejection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67789309/