async函数内同步throw错误时,返回的Promise立即进入rejected状态;引擎在throw执行的同一宏任务中调用Promise.reject,Error实例直接作为reason传递,等价于手动Promise.reject,不经过微任务队列。

async 函数内部 主动 throw new Error(...) 时,返回的 Promise 立刻进入 rejected 状态——这不是“延迟触发”或“异步转换”,而是 JavaScript 引擎在执行到 throw 语句那一刻,就同步完成 Promise 的 reject 操作。关键在于:async 函数本质是语法糖,其底层由 Promise 构造逻辑和执行上下文共同保障这一即时性。
async 函数返回的 Promise 由引擎自动封装
声明 async 函数,等价于定义一个“自动包裹结果”的函数:
- 函数体未抛错 → 返回值被
Promise.resolve()包装,状态为 fulfilled - 函数体同步 throw(无论位置)→ 引擎立即调用
Promise.reject(throw 的值),状态为 rejected - 这个 reject 不依赖微任务队列,也不等待 await;它发生在 throw 执行的**同一轮宏任务中**
throw 的值就是 reject 的 reason,不经过任何中间包装
你 throw 的 Error 实例,就是 Promise 被 reject 时传给 catch 或 .catch() 的原始值:
-
throw new TypeError("timeout")→ Promise reject 原因就是该 TypeError 实例,含完整 stack - 不是先生成 Error、再转成字符串、再塞进 Promise;Error 对象直接作为 reason 传递
- 这也意味着,
.catch(e => console.log(e instanceof Error))会输出 true
与普通 Promise.reject() 行为完全一致
async 函数中 throw 错误,语义上等价于手动调用 Promise.reject:
-
async () => { throw new Error("x"); }≡() => Promise.reject(new Error("x")) - 两者都跳过 resolve 流程,直接触发 Promise 的 rejected 分支
- 后续链式调用(如 .then(...).catch(...))无法捕获该错误,除非在正确位置添加 catch
错误不会“卡在 await 后面”,而是中断整个 async 执行流
await 只影响后续代码的执行时机,不影响 throw 的即时性:
- 即使 await 后面还有 10 行代码,只要 throw 发生在它们之前,Promise 就立刻 rejected
- await 表达式本身不会“吞掉”错误;它只是暂停,而 throw 是同步中断
- 若 throw 出现在 await 表达式右侧(如
await Promise.reject(...)),那属于 Promise 链的 reject,而非函数体 throw


















