为什么 try catch 块不捕获 promise 异常?
Why doesn't the try catch block catch the promise exception?
我对使用 promises 进行错误处理感到困惑。答案可能很明显,但我不明白。
我有以下示例代码:
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 块不应该处理错误吗?
我可以看出您的问题有两个可能的方面:
test
中抛出的错误在 test
的同步(非异步)部分。为什么是 promise 拒绝而不是同步异常?
来自 test()
的承诺被拒绝了,为什么 catch
没有捕捉到拒绝?
#1 - 为什么拒绝?
因为即使 async
函数在其工作的同步部分抛出异常,这也只是拒绝了它 returns 的承诺,它 不会 引发同步错误。这只是 async
函数设计过程中做出的一个设计决定,而且是一个聪明的决定——如果在函数的同步部分抛出时是一个同步错误,但之后又是一个 promise 拒绝,那将是混乱和困难的了解。所以很简单:投入一个 async
函数总是拒绝它的承诺。
(这与 promise 构造函数如何处理您传递给它的执行器回调是一致的。当您执行 new Promise((resolve, reject) => /*...*/})
时,promise 构造函数会同步调用您的函数,但如果您在调用期间抛出,它会使用你抛出什么来拒绝承诺而不是允许它作为同步异常继续。)
#2 - 为什么 catch
块没有捕捉到拒绝?
因为您没有使用 await
。当您 await
承诺时,承诺拒绝只是例外。如果您使用 promise 方法 then
/catch
/finally
来附加处理程序,拒绝将通过调用拒绝处理程序来处理,而不是通过异常机制来处理。
所以要么使用 promise 方法来附加履行和拒绝处理程序:
test()
.then(result => {
// ...use `result` here...
})
.catch(error => {
// ...handle/report error here...
});
或在 async
函数中使用 await
(如果您的环境中有顶级 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...
}
我对使用 promises 进行错误处理感到困惑。答案可能很明显,但我不明白。
我有以下示例代码:
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 块不应该处理错误吗?
我可以看出您的问题有两个可能的方面:
test
中抛出的错误在test
的同步(非异步)部分。为什么是 promise 拒绝而不是同步异常?来自
test()
的承诺被拒绝了,为什么catch
没有捕捉到拒绝?
#1 - 为什么拒绝?
因为即使 async
函数在其工作的同步部分抛出异常,这也只是拒绝了它 returns 的承诺,它 不会 引发同步错误。这只是 async
函数设计过程中做出的一个设计决定,而且是一个聪明的决定——如果在函数的同步部分抛出时是一个同步错误,但之后又是一个 promise 拒绝,那将是混乱和困难的了解。所以很简单:投入一个 async
函数总是拒绝它的承诺。
(这与 promise 构造函数如何处理您传递给它的执行器回调是一致的。当您执行 new Promise((resolve, reject) => /*...*/})
时,promise 构造函数会同步调用您的函数,但如果您在调用期间抛出,它会使用你抛出什么来拒绝承诺而不是允许它作为同步异常继续。)
#2 - 为什么 catch
块没有捕捉到拒绝?
因为您没有使用 await
。当您 await
承诺时,承诺拒绝只是例外。如果您使用 promise 方法 then
/catch
/finally
来附加处理程序,拒绝将通过调用拒绝处理程序来处理,而不是通过异常机制来处理。
所以要么使用 promise 方法来附加履行和拒绝处理程序:
test()
.then(result => {
// ...use `result` here...
})
.catch(error => {
// ...handle/report error here...
});
或在 async
函数中使用 await
(如果您的环境中有顶级 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...
}