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

tim*_*amp 4 javascript exception es6-promise

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

我有以下示例代码:

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

try {
  test().then()
}
catch(err){
  alert('error: ' + err.toString())
}
Run Code Online (Sandbox Code Playgroud)

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

T.J*_*der 13

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

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

    \n
  2. \n
  3. 承诺被test()拒绝了,为什么不catch抓住那个拒绝呢?

    \n
  4. \n
\n

#1 - 为什么会被拒绝?

\n

因为即使async函数在其工作的同步部分期间抛出异常,也只会拒绝它返回的 Promise,不会引发同步错误。这只是函数设计过程中做出的一个设计决策async,如果在函数的同步部分抛出时出现同步错误,但之后又出现承诺拒绝,那么这是一个聪明的\xc2\xa0\xe2\x80\x94混乱且难以理解。所以很简单:抛出一个async函数总是会拒绝它的承诺。

\n

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

\n

#2 - 为什么拒绝不会被catch块捕获?

\n

因为你没有使用await. await仅当您执行 Promise时,Promise 拒绝才属于例外情况。// 如果使用 Promise 方法then附加处理catch程序finally,则拒绝是通过调用拒绝处理程序来处理的,而不是通过异常机制来处理。

\n

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

\n
test()\n.then(result => {\n    // ...use `result` here...\n})\n.catch(error => {\n    // ...handle/report error here...\n});\n
Run Code Online (Sandbox Code Playgroud)\n

或者await在函数中使用(或者在模块的顶层使用,如果您的环境中async有顶层):await

\n
// In an `async` function (or the top level of a module in cutting-edge environments)\ntry {\n    const result = await test();\n    // ...use `result` here...\n}\ncatch(err){\n    // ...handle/report error here...\n}\n
Run Code Online (Sandbox Code Playgroud)\n