为什么在异步函数中捕获异常后仍会引发异常?

时间:2020-08-20 15:54:18

标签: javascript node.js error-handling async-await

当捕获到异常时,其余代码仍将执行。

function bad(){
    //throw new Error('I am an exception')
    return Promise.reject("I am an exception")
}

(
 async function (){
      let  msg = await bad().catch( e=>console.log("This is an error: " + e))
      console.log("I want to stop before executing this line ")
 }
)()

我正在尝试以这种方式捕获异常,而不是尝试捕获

我的第一个问题是在发现错误之后如何阻止代码到达其余代码。

第二个问题是,如果我用注释掉的抛出错误替换了Promise拒绝,则不会捕获抛出的异常错误,为什么?

1 个答案:

答案 0 :(得分:3)

因为您正在使用catch处理程序将拒绝转化为实现。 await将等待catch返回的承诺,该承诺不会被拒绝。因此,没有理由代码不会继续,因为await仅看到实现(从未拒绝)的承诺。

请记住,catch返回了一个新的promise,该promise将根据拒绝处理程序的操作来解决。您的拒绝处理程序可以通过有效地返回undefined来兑现错误,从而兑现承诺。

就好像您这样做:

async function (){
    let msg;
    try {
        msg = await bad();
    } catch (e) {
        console.log("This is an error: " + e);
    }
    console.log("I want to stop before executing this line ")
}

在评论中您已经问过:

因此,除了将我的所有代码都包含在try块中之外,别无选择,并且如果我没有更多要遵循的代码,则仅使用单行.catch()吗?

只是为了解决问题:通常,最好的办法是根本不处理代码顶层输入点以外的任何函数中的错误(例如,在代码顶层调用的函数)或通过事件处理程序)。过早处理错误是经典的反模式。允许它们传播给呼叫者,并在其中进行集中处理。

但是,在适合于此级别处理错误的情况下,可以,try / catch可能是您最好的选择,并在try块中采用以下逻辑:

async function() {
     try {
         let msg = await bad();
         console.log("I want to stop before executing this line ")
     } catch (e) {
         console.log("This is an error: " + e);
     }
}

它的另一个优点是,在包含范围中没有要使用的变量没有声明。如果“一个班轮”对您很重要,那么.catchcatch之间就没有多大区别了:

async function() {
     try {
         let msg = await bad();
         console.log("I want to stop before executing this line ")
     } catch (e) { console.log("This is an error: " + e); }
}

或者您可以返回某种标志值:

async function() {
     let msg = await bad().catch(e => { console.log("This is an error: " + e); return null; });
     if (msg === null) {
         return;
     }
     console.log("I want to stop before executing this line ")
}

但是坦率地说,这确实与潮流背道而驰。 :-)