为什么无await前缀直接返回async函数时try catch会被忽略
问题原理解答
这个现象的核心原因和async函数的运行机制、try-catch的捕获范围直接相关:
try-catch只能捕获当前同步调用栈内抛出的异常,异步场景下的错误如果没有被主动抛到当前执行上下文,无法被捕获。async函数的所有返回值都会自动封装为Promise对象:如果async函数内部抛出错误,不会直接向外抛出同步异常,而是会将返回的Promise标记为rejected状态,错误作为该Promise的拒因。
情况1:调用async函数不加await
bar()执行后返回一个rejected状态的Promise,这个错误是绑定在Promise对象上的异步错误,没有被await处理的话,不会作为同步异常抛到当前try块的执行上下文里,所以catch块完全不会触发。foo函数最终会把这个rejected的Promise作为返回值,只能通过foo().catch()才能拿到这个错误。
async function foo() { try { return bar() } catch(e) { throw new Error('never see this') } } async function bar() { throw new Error('only see this') } foo().then()
情况2:调用async函数加await
await的作用就是暂停当前async函数的执行,等待后方Promise的状态变更:如果Promise变为rejected,await会把拒因作为异常抛出到当前上下文,所以这个错误就能被外层的try-catch捕获到。
async function foo() { try { return await bar() } catch(e) { throw new Error('now this works') } } async function bar() { throw new Error('foo') } foo().then()
情况3:调用非async同步函数
普通同步函数的执行完全在当前调用栈内,内部抛出的错误是同步异常,直接就会进入当前上下文的try-catch块,和外层是不是async函数无关。
async function foo() { try { return bar() } catch(e) { throw new Error('now this works') } } function bar() { throw new Error('foo') } foo().then()
内容的提问来源于stack exchange,提问作者MCMatan
相关产品推荐
相关产品推荐

