为什么 try catch 块没有捕获 Promise 异常?

2024-05-16

我对承诺的错误处理感到困惑。答案可能很明显,但我不明白。

我有以下示例代码:

var test = async function(){
  throw new Error('Just another error')
}

try {
  test().then()
}
catch(err){
  alert('error: ' + err.toString())
}

在我的浏览器中我没有收到警报Uncaught (in promise) Error在控制台中。这是为什么? try..catch 块不应该处理错误吗?


我可以看到你的问题有两个可能的方面:

  1. 抛出的错误test位于同步(非异步)部分test。为什么是承诺拒绝而不是同步异常?

  2. 来自的承诺test()被拒绝了,为什么不catch抓住那个拒绝吗?

#1 - 为什么会被拒绝?

因为即使一个async函数在其工作的同步部分期间抛出,这只是拒绝它返回的承诺,它doesn't引发同步错误。这只是在设计过程中做出的设计决定async函数,而且是一个聪明的函数——如果在放入函数的同步部分时出现同步错误,但之后又出现 Promise 拒绝,那么它将是混乱且难以理解的。所以很简单:扔进去async函数总是拒绝它的承诺。

(这与 Promise 构造函数处理您传递给它的执行器回调的方式一致。当您这样做时new Promise((resolve, reject) => /*...*/}),promise 构造函数同步调用您的函数,但如果您在调用期间抛出异常,它会使用您抛出的异常来拒绝 Promise,而不是允许它作为同步异常继续运行。)

#2 - 为什么拒绝没有被捕获catch block?

因为你没有使用await。承诺被拒绝只是例外,当你await兑现承诺。如果您使用承诺方法then/catch/finally要附加处理程序,拒绝是通过调用拒绝处理程序来处理的,而不是通过异常机制。

因此,要么使用 Promise 方法来附加履行和拒绝处理程序:

test()
.then(result => {
    // ...use `result` here...
})
.catch(error => {
    // ...handle/report error here...
});

Or use await in an async函数(或者在模块的顶层,如果你有顶层await在您的环境中):

// In an `async` function (or the top level of a module in cutting-edge environments)
try {
    const result = await test();
    // ...use `result` here...
}
catch(err){
    // ...handle/report error here...
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 try catch 块没有捕获 Promise 异常? 的相关文章

随机推荐