← 事件循环 · 任务、微任务,与那一圈的所有时机 / 一圈是怎么转的:同步 → 微任务 → 渲染 → 下一个宏任务 待审核 1 / 6
the loop · 调用栈 + 宏任务 + 微任务

一圈是怎么转的:同步 → 微任务 → 渲染 → 下一个宏任务

JavaScript 是单线程的:同一时刻只有一段代码在跑。那「同时」处理点击、定时器、网络回包靠什么?靠一个持续运转的循环——事件循环 (event loop)。它的规则可以概括为一句:取一个宏任务执行完 → 把微任务全部清空 →(到时机就渲染)→ 再取下一个宏任务。本页把这套规则做成一个可单步执行的模拟器,直观说明「为什么 Promise.then 总在 setTimeout(,0)setTimeout(\dots , 0) 之前执行」。

把整段 <script> 也看成「第一个宏任务」:它同步跑完,期间排下的 setTimeout宏任务队列Promise.then / queueMicrotask微任务队列。点**「下一步」**观察事件循环如何逐步推进。

关键规则:微任务队列「一次清空到底」——清空过程中新产生的微任务也算这一轮,要一并清完。而宏任务「一次只取一个」,取出一个后就先清空微任务。因此大量微任务会把渲染和下一个宏任务无限期推后(这一特性在微任务页详述)。

渲染并非每一圈都发生。浏览器大约每 16.7ms (≈60fps) 提供一次「渲染机会」,期间可能已执行了多个宏任务。本模拟器为说明顺序做了简化:把每个宏任务边界都画成一次渲染机会。真实浏览器会合并 / 跳过渲染,rAF 与 0ms 定时器谁先并不保证(取决于当前是否正好到了渲染时机)。