async/await 是基于 Promise 和 Generator 语义的语法糖,async 函数始终返回 Promise,await 实现“暂停-等待-恢复”的微任务调度,错误通过 Promise 链统一处理。

async 和 await 不是新机制,而是 JavaScript 引擎在编译和执行阶段自动转换的语法糖,核心依赖 Promise 和 Generator 的协作逻辑。它让异步流程看起来像同步代码,但实际调度仍由事件循环和微任务队列控制。
async 函数本质是 Promise 构造器
声明一个 async 函数,等价于返回一个 Promise:
- async function foo() { return 42; } 编译后行为 ≈ function foo() { return Promise.resolve(42); }
- 哪怕函数体里没写 await,也强制包装成 Promise;若抛错,则等价于 Promise.reject(err)
- 返回非 Promise 值时,引擎自动调用 Promise.resolve() 包装;返回 Promise 则直接透传(不叠加)
await 触发的是“暂停-等待-恢复”三步微任务调度
await 并不是阻塞线程,而是在当前执行上下文中插入一次“让出控制权”的操作:
- 遇到 await 表达式时,引擎暂停该 async 函数的执行,把后续逻辑封装为一个微任务回调
- 被 await 的值若不是 Promise,会先用 Promise.resolve() 转换;然后监听其状态变化
- 一旦 Promise 变为 fulfilled 或 rejected,微任务队列触发,恢复函数执行,并把结果赋给 await 左侧变量
底层没有运行时生成器对象,但语义上模拟 Generator + 自动执行器
早期用 Generator 实现类似逻辑需手动写 next() 和 Promise 链,async/await 把这套流程完全内建到语言层面:
- 引擎不真的创建 Generator 实例,但内部状态管理(如暂停点、上下文保存)与 Generator 状态机高度相似
- 每个 await 是一个隐式 yield 点;函数恢复时,从上次暂停处继续,变量作用域、this、try-catch 等上下文都保持完整
- 这种状态保存不是靠闭包堆叠,而是由 JS 引擎在调用栈外维护一个轻量级执行上下文(V8 中称为 AsyncFunctionObject)
错误处理统一走 Promise 链,但语法更自然
await 后的 Promise reject 不会冒泡到全局,而是被 async 函数捕获并转为 rejected Promise:
- await Promise.reject('oops') 会导致整个 async 函数返回 rejected Promise
- 可用 try/catch 捕获,效果等同于 .catch();未捕获则交由调用方处理
- 多个 await 连续写时,任一失败都会中断后续执行,符合“同步风格”的直觉


















