await 后的代码由引擎自动作为微任务调度,本质是 promise.then 的语法糖;当 await 表达式求值完成后,其后续逻辑被隐式注册为 promise 的 onfulfilled 回调,并在当前宏任务结束后立即执行。

await 后的代码本身不会“被推入”微任务队列,而是由 JavaScript 引擎在 await 表达式求值完成后,**自动将后续执行逻辑作为微任务调度**。这个机制不是开发者手动入队,而是 async/await 语法底层基于 Promise 和微任务(microtask)规范实现的隐式行为。
await 的本质是 Promise.then 的语法糖
当执行到 await expression 时:
- 如果
expression不是 Promise,引擎会立即用Promise.resolve(expression)包装它; - 引擎暂停当前 async 函数的执行(不阻塞主线程),并隐式地在该 Promise 上注册一个
.then(onFulfilled)回调; - 这个
onFulfilled回调里,就包含了await后面的那行(或那些)代码; - 而 Promise 的
.then回调,根据 HTML 规范和 ES 规范,**必须作为微任务执行**。
微任务队列的触发时机很明确
一旦 await 后的 Promise 变为 fulfilled(或 rejected),且当前调用栈清空(即本轮宏任务结束前),引擎就会把对应的 onFulfilled(即 await 后续代码)推入微任务队列,并在本轮宏任务结束后、下一轮宏任务开始前立即执行它。
例如:
async function foo() {console.log('1');
await Promise.resolve();
console.log('2');
}
foo();
console.log('3');
输出顺序是 1 → 3 → 2,因为 console.log('2') 被包裹在 Promise.then 的微任务中,在同步代码(console.log('3'))执行完后才运行。
你无法也不需要手动把它“推入”微任务队列
开发者不能也不应该用 queueMicrotask() 或其他方式去模拟 await 后续的调度——那是引擎内部保障的行为。如果你写:
queueMicrotask(() => console.log('2'));
这等价于多加了一层微任务,和原生 await 的执行逻辑不等价,还可能引入不必要的延迟或嵌套。
注意:await 暂停的是函数上下文,不是线程
async 函数执行到 await 时,会保存当前执行上下文(如变量环境、词法环境),然后退出;等到微任务执行时,引擎恢复该上下文继续执行。整个过程不涉及线程挂起或系统级等待,完全是事件循环 + 微任务调度的协作结果。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











