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

为何含try/catch的async/await代码仍抛出未捕获错误?

为什么这段代码会抛出未捕获异常?

先看核心代码的执行逻辑:

(async() => {
  try {
    let prom = promiseThing(); // 这里立刻执行promiseThing,返回一个rejected的Promise

    await timeout(); // 等待1秒
    await prom; // 1秒后才尝试处理这个rejected Promise
    console.log("get here");

  } catch (err) {
    console.log(err);
  }
})();

async function promiseThing() {
   throw new Error("an error");
}

问题根源:Rejected Promise的“悬空”时间

  • 当你调用promiseThing()时,这个异步函数会立即执行,里面的throw会让它返回的Promise直接进入rejected状态。
  • 但此时你并没有立刻用await或者.catch()去处理这个rejected Promise,而是先等待timeout()的1秒延迟。
  • JavaScript引擎会监控所有Promise的状态:如果一个Promise变成rejected后,在事件循环的下一轮之前还没有被任何错误处理逻辑绑定,就会触发“未捕获的Promise rejection”错误。

1秒的延迟足够让引擎判定这个rejected Promise没有被处理,所以提前抛出异常,等你后来执行await prom的时候,这个错误已经被引擎报过了,不会再被try/catch捕获。

为什么替换成Promise.resolve()就正常?

如果把await timeout()换成await Promise.resolve(),这个等待会立即完成,几乎没有时间间隔:

  • promiseThing()返回rejected Promise后,马上就执行到await prom,try/catch会立刻捕获这个rejection,不会出现“悬空”的rejected Promise,自然不会触发未捕获异常。

同理,如果timeout()直接返回Promise.resolve(),也是一样的道理——没有延迟,错误处理逻辑会及时绑定到rejected Promise上。

Promise链的情况为什么一致?

用Promise链写类似逻辑时,比如:

(() => {
  const prom = promiseThing();
  timeout().then(() => {
    return prom;
  }).catch(err => console.log(err));
})();

同样会出现未捕获异常:因为prom变成rejected后,要等timeout()的1秒才会进入.then()去处理它,这期间prom的rejection没有被绑定任何错误处理,引擎同样会提前抛出未捕获异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 23:32:38