async函数通过await和隐式promise返回触发微任务,await后值决定入队时机:普通值立即包装为promise并入队,原生promise待settled后入队;其返回promise的决议也走微任务,优先级高于settimeout。

async 函数本身不直接“调度”微任务,而是通过隐式返回 Promise 和 await 表达式,自然触发 JavaScript 的微任务队列机制。关键在于理解 await 后的值如何影响微任务的入队时机。
await 会把后续代码包装成微任务
当执行到 await expression 时:
- 如果 expression 是普通值(如 42、"hello"),JavaScript 会立即用 Promise.resolve() 包装它,然后将 await 后面的语句(即函数剩余逻辑)作为微任务推入队列;
- 如果 expression 是原生 Promise(如 fetch() 返回的 Promise),则等待其 settled(fulfilled/rejected)后,再把后续代码作为微任务入队;
- 注意:这个微任务是 PromiseJobs,属于标准微任务,优先级高于 setTimeout 回调(宏任务)。
async 函数返回的 Promise 决议也走微任务
async 函数总是返回一个 Promise。即使函数体中没有 await,或 return 一个同步值:
- return 123 等价于 return Promise.resolve(123);
- 该 Promise 的 fulfilled 状态会在当前任务结束后、下一个宏任务前,以微任务形式通知 then/catch 回调;
- 所以 asyncFn().then(...) 的回调一定会在当前同步代码之后、setTimeout 之前执行。
多个 await 会链式产生微任务
每个 await 都可能引入一次微任务排队(取决于右侧是否需异步等待):
- 连续 await 两个已 resolve 的 Promise,会形成两个嵌套微任务;
- 实际执行顺序是:第一个 await 完成 → 推入微任务A → 执行微任务A(进入第二个 await)→ 推入微任务B → 执行微任务B;
- 这和手写 Promise.resolve().then(...).then(...) 的链式微任务行为一致。
不触发微任务的常见误解
以下情况 不会 新增微任务:
- async 函数声明本身(只是定义,不执行);
- 调用 async 函数但未 await 或未接 .then —— 此时 Promise 已创建并开始执行,但后续逻辑尚未入队;
- await 一个已经 fulfilled 的 Promise(如 await Promise.resolve(1))仍会入队微任务,但这是规范要求,不是“可省略”的优化。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











