加载中...
事件循环是 JavaScript 单线程运行时处理异步任务的调度机制,通过宏任务队列与微任务队列的轮转,让耗时操作不阻塞主线程,是理解 setTimeout、Promise、async/await 执行顺序的基础。

| 微任务来源 | Promise.then / queueMicrotask / MutationObserver |
| 宏任务来源 | setTimeout / setInterval / I/O / UI 渲染 |
| 规范文档 | HTML Living Standard §8.1.7 |
JavaScript 引擎只有一个调用栈(Call Stack)。同步代码依次入栈执行;遇到 setTimeout 这类异步 API 时,浏览器的 Web API 层计时,时间到后把回调推入宏任务队列(Macro Task Queue)。每当调用栈清空,事件循环先把当前所有微任务(Microtask)执行完——Promise 的 .then、queueMicrotask、MutationObserver 回调均属此类——再取下一个宏任务入栈。Node.js 的事件循环基于 libuv,结构与浏览器类似但多了 I/O 阶段和 process.nextTick 优先级。[1]
代码 setTimeout(fn, 0) 并不立即执行,而是等当前宏任务及所有微任务跑完才轮到它。所以 Promise.resolve().then(A) 和 setTimeout(B, 0) 同时注册,A 永远先于 B。Philip Roberts 在 JSConf EU 2014 的演讲「What the heck is the event loop anyway?」让这个机制被大众熟知,他开发的可视化工具 Loupe 至今仍是学习利器。2015 年 ECMAScript 6 正式将微任务(PromiseJob)纳入规范,使执行顺序在不同引擎之间有了一致保证。

| 微任务来源 | Promise.then / queueMicrotask / MutationObserver |
| 宏任务来源 | setTimeout / setInterval / I/O / UI 渲染 |
| 规范文档 | HTML Living Standard §8.1.7 |
登录 后参与讨论
暂无讨论,来发表第一条评论吧