一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

JavaScript 中 async 函数内部异常二次抛出的逻辑

时间:2026-07-09 12:44:47 编辑:袖梨 来源:一聚教程网

async函数的异常处理本质是Promise链的错误传播,同步抛出异常或await rejected Promise均使返回Promise变为rejected状态,throw在async内等价于Promise.reject()。

async 函数内部的异常处理,本质仍是 Promise 链的错误传播机制。它不会“自动捕获”错误,而是把同步抛出的异常或 await 后 rejected 的 Promise,统一转换为函数返回 Promise 的 rejection 状态。

同步代码抛出异常 → 返回 Promise 被 reject

在 async 函数中,任何同步位置(比如 await 前、或未被 try/catch 包裹的语句)抛出异常,都会立即终止执行,并让整个 async 函数返回的 Promise 进入 rejected 状态。

例如:

async function foo() {
  throw new Error('boom');
  console.log('never runs'); // 不会执行
}
foo().catch(err => console.log(err.message)); // 'boom'

await 一个 rejected Promise → 等效于 throw

await 后跟一个 rejected 的 Promise 时,JavaScript 引擎会将其“解包”并以 throw 的形式重新抛出该 rejection 原因(即 Promise 的 reason),行为等同于同步 throw。这使得错误可以被上层 try/catch 捕获,也可继续向上冒泡。

立即学习“Java免费学习笔记(深入)”;

例如:

async function bar() {
  try {
    await Promise.reject('failed');
  } catch (e) {
    console.log('caught:', e); // 'caught: failed'
    throw e; // 二次抛出 —— 此处不是“新抛”,而是延续 rejection 流程
  }
}
bar().catch(e => console.log('outer:', e)); // 'outer: failed'

二次抛出的本质:延续 Promise rejection 链

在 async 函数中用 throw 显式抛出值(无论是否在 catch 块内),效果都是让当前 async 函数返回的 Promise 变为 rejected,且 reason 就是所 throw 的值。它不是“重新触发异常”,而是构造一个新的 rejected Promise 并返回。

  • throw 在 async 内部 = 返回 Promise.reject(value)
  • 未被捕获的 await rejection = 自动转为 throw,再变成 Promise.reject(reason)
  • 在 try/catch 中 throw,只是提前结束当前 async 执行,并把控制权交还给调用方的 Promise 链

常见误区:不是“异常重抛”,而是“Promise 状态传递”

async/await 是语法糖,底层始终基于 Promise。所谓“二次抛出”,其实是开发者在错误处理流程中主动选择不消化错误,而是通过 throw 让外层 Promise 继续处于 rejected 状态。它不涉及 JavaScript 异常栈的“再抛”,也不改变原始错误对象(除非显式创建新 Error)。

因此,正确理解的关键是:async 函数的返回值永远是一个 Promise;它的“异常逻辑”就是 Promise 的 rejection 传递逻辑。

热门栏目