es6 承诺:catch 方法不会捕获承诺中引发的异常



以下代码

const run = async() => {
try {
const p = Promise.reject()
p.catch(() => console.log('exception caught'))
await p
console.log('flow completed')
} catch {
console.log('flow interrupted')
}
}
run()

打印以下输出:

exception caught
flow interrupted

这意味着,即使 catch 方法正在运行,也不会捕获异常

现在,如果我进行这个看似无关紧要的编辑并将捕获链接在 promise 定义之后

const run = async() => {
try {
const p = Promise.reject().catch(() => console.log('exception caught'))
await p
console.log('flow completed')
} catch {
console.log('flow interrupted')
}
}
run()

输出变为

exception caught
flow completed

我尝试定义承诺,例如const p = new Promise((resolve, reject) => {setTimeout(reject, 100)})认为在拒绝承诺之前设置捕获可能很重要,但它并没有改变任何东西

我正在使用节点 12.16.1 运行这些测试

谁能解释为什么第一个代码示例中没有捕获异常,而是在第二个代码示例中捕获异常?

你在那里分叉你的链。(哇,这听起来很奇怪...

您正在执行等效的操作:

const p = Promise.reject();
p.catch(...);
p.catch(...);

这是承诺链中的两个独立分叉,将被独立捕获。p被拒绝,p.catch恢复它,以处理p.catch之后的任何内容。任何没有被p.catch束缚的东西都会独立地经历p的拒绝。既然你await p,你就不在链条的分叉处。

p被拒绝并触发任何和所有附加的catch处理程序,其中可以有多个处理程序。 另一方面,p.catch(...)返回一个新的成功承诺。