async/await 依赖微任务机制实现异步控制:await 将后续逻辑注册为 promise.then 的微任务,async 函数返回值自动包装为 promise.resolve() 并进入微任务队列,错误处理同样走微任务路径,确保微任务优先于宏任务执行。

async/await 的执行离不开微任务机制——它不是“暂停线程”,而是把函数后续逻辑包装成微任务,等 Promise 完成后由事件循环调度执行。
await 本质是注册微任务
当代码执行到 await 表达式时,JavaScript 引擎会:
- 对右侧表达式求值;若结果是 Promise,则暂停当前 async 函数的执行上下文
- 将该 Promise 的 then 回调(即 await 后面那部分代码)注册为微任务
- 立即让出控制权,继续执行同步代码或其它微任务
也就是说,await 并不自己创建微任务,而是依赖 Promise.then 的微任务语义。只要 Promise 状态变为 fulfilled 或 rejected,其 then/catch 回调就会被推入微任务队列。
async 函数返回值自动进入微任务链
async 函数无论 return 什么,都隐式包装为 Promise.resolve():
-
async function f() { return 123 }等价于function f() { return Promise.resolve(123) } - 这个 Promise 的 resolve 值,会在当前宏任务结束、微任务清空前,被推入微任务队列等待执行
- 所以调用 async 函数后,.then() 或 await 它的地方,总是在微任务阶段拿到结果
执行顺序体现微任务优先级
看这段典型代码:
console.log('1');
async function foo() {
console.log('2');
await Promise.resolve();
console.log('3');
}
foo();
console.log('4');
输出顺序是:1 → 2 → 4 → 3。原因:
- '1' 和 '2' 是同步执行
- await 触发 Promise.resolve().then(() => console.log('3')),该回调进入微任务队列
- '4' 是同步代码,紧随其后执行
- 本轮宏任务结束,事件循环立刻处理微任务队列 → 执行 '3'
错误处理也走微任务路径
如果 await 的 Promise 被 reject,对应的 catch 或 try/catch 中的后续逻辑,同样作为微任务加入队列:
- reject 不会中断当前宏任务,但会触发微任务中的错误传播
- 这意味着错误不会立即抛出,而是在当前同步代码跑完、微任务清空前才被处理
- 这也是为什么在 async 函数里 throw 错误,外层 .catch() 也是微任务级别响应











