You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

async函数在try/catch中的执行上下文与错误捕获疑问

问题解析:async/await中try/catch的错误捕获机制

示例代码

async function foo() {
  try {
    const response = await fetch("https://www.xxx.xxx");
    const data = await response.json();
    console.log(data);
  } catch (e) {
      console.log("Error!!: ", e);
    }
}
foo();
console.log('111');

执行结果

先输出 111,再输出 Error!!: TypeError: Failed to fetch

核心困惑

当console.log('111')执行时,foo的执行上下文已经移出调用栈,为什么foo里的catch还能捕获到fetch的错误?

详细执行流程与错误捕获原理

  1. 调用foo(),foo的执行上下文被创建并推入调用栈。
  2. 进入try块,执行fetch("https://www.xxx.xxx"):fetch的执行上下文入栈,发起网络请求后返回一个pending状态的Promise,随后fetch的执行上下文出栈。
  3. 遇到await关键字:JS引擎会暂停foo的执行,将foo的执行上下文从调用栈中弹出,但会完整保存上下文的所有状态(包括try/catch的作用域、变量、暂停位置等)。同时,为fetch返回的Promise注册两个回调:
    • 如果Promise变为resolved,就恢复foo的执行上下文,继续执行const data = await response.json()及后续代码;
    • 如果Promise变为rejected,就恢复foo的执行上下文,直接进入catch块处理错误。
      这组回调会被加入微任务队列等待执行。
  4. foo暂停后,调用栈为空,全局代码继续执行console.log('111'),控制台输出111。
  5. 全局代码执行完毕,调用栈再次为空,JS引擎开始处理微任务队列。此时fetch的网络请求失败,Promise状态变为rejected,对应的错误处理回调被取出并推入调用栈。
  6. foo的执行上下文被重新恢复并推入调用栈,因为Promise是rejected状态,所以直接进入try块对应的catch分支,执行错误输出逻辑,控制台打印错误信息。

简单来说:await只是暂停foo的执行,而非终结,foo的上下文会被保留。当Promise状态改变时,foo的上下文会被恢复,此时try/catch的作用域依然有效,rejected的错误会被直接导向catch块——整个过程中,try/catch始终覆盖着await操作的逻辑,不管中间是否有暂停和上下文的移出/恢复。

内容的提问来源于stack exchange,提问作者skwFE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 21:28:34