Promise / async 输出题

先理解原理和示例,再练习完整口述与追问。

同步执行器、微任务入队、await 续体、定时器。

做输出题先分同步执行、微任务登记和任务执行,按真正登记顺序维护队列。Promise executor 同步,then 回调异步;await 后续会在条件满足后恢复,不能把整个 async 函数一开始就扔到异步队列。

阅读下方原题时,先在纸上写同步日志,再记录每次 then 与 await 的加入位置,最后处理定时器。then 内新增 then 会排到当前已有微任务之后;返回另一个 Promise 还涉及采纳,不应只按源码缩进顺序猜。

题目运行环境要明确,浏览器与 Node 的 nextTick、I/O 阶段有差异。具体答案应来自逐步推演和运行验证,不靠“宏微口诀”代替。

先执行全部同步代码。Promise 执行器同步执行,then 和 await 后续通过异步调度继续;处理微任务时新加入的微任务排在已有任务之后。本例在浏览器主线程普通脚本中输出 A E G C F D B,不能把 Node 特有的 nextTick 等规则擅自加进来。

js
console.log('A')
setTimeout(() => console.log('B'), 0)
Promise.resolve().then(() => {
  console.log('C')
  Promise.resolve().then(() => console.log('D'))
})
async function run() {
  console.log('E')
  await Promise.resolve()
  console.log('F')
}
run()
console.log('G')

**逐步解释:**同步先输出 A,注册定时器,安排 C,调用 run 输出 E,安排 await 续体 F,再输出 G。微任务先 C,C 把 D 追加到 F 后面,所以再 F、D。定时器 B 最后。这里没有承诺每次微任务清空后浏览器都立即绘制。