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 等规则擅自加进来。
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 最后。这里没有承诺每次微任务清空后浏览器都立即绘制。