🌐 事件循环的本质
1. 谁在控制事件循环?
- 不是JavaScript语言本身,而是运行环境(浏览器/Node.js)的内置机制。
- 就像操作系统的"任务调度器",自动管理任务执行顺序。
2. 为什么需要事件循环?
场景 | 无事件循环 | 有事件循环 |
---|
同步任务 | 直接阻塞执行 | 直接执行 |
异步任务 | 卡死页面 | 通过队列非阻塞处理 |
🔧 运行环境对比
特性 | 浏览器事件循环 | Node.js事件循环 |
---|
实现方 | 浏览器渲染引擎(如V8) | libuv库 |
微任务 | Promise.then/MutationObserver | process.nextTick/Promise |
宏任务 | setTimeout/UI渲染 | setImmediate/文件I/O |
⚙️ 事件循环完整流程

关键阶段(浏览器)
- 同步代码执行
- 微任务清空(VIP通道)
-
- Promise.then
- MutationObserver
- queueMicrotask
- 渲染DOM(如有需要)
- 宏任务执行(普通通道)
💡 深度理解技巧
1. 延迟0ms的setTimeout
setTimeout(() => console.log("宏任务"), 0);
Promise.resolve().then(() => console.log("微任务"));
console.log("同步");
2. 微任务嵌套
Promise.resolve().then(() => {
console.log("微任务1");
Promise.resolve().then(() => console.log("嵌套微任务"));
});
- 微任务执行期间产生的新微任务会立即执行,不会等到下一轮循环
🚨 常见误区澄清
误区1:"事件循环是JS引擎的一部分"
- ✅ 事实:JS引擎(如V8)只负责执行代码,事件循环由宿主环境实现
误区2:"微任务比宏任务快"
误区3:"requestAnimationFrame是宏任务"
- ✅ 事实:属于渲染阶段的任务,既不是宏任务也不是微任务
🎯 面试黄金题
题1:说出下面代码的输出顺序
console.log(1);
setTimeout(() => console.log(2), 0);
Promise.resolve()
.then(() => console.log(3))
.then(() => console.log(4));
console.log(5);
答案:1 → 5 → 3 → 4 → 2
题2:如何实现优先执行的微任务?
Promise.resolve().then(fn);
queueMicrotask(fn);
📜 终极总结表
概念 | 触发方式 | 执行时机 | 典型API |
---|
同步任务 | 直接调用 | 立即执行 | console.log |
微任务 | 异步回调 | 同步代码后立即执行 | Promise.then |
宏任务 | 事件/定时器 | 微任务队列清空后执行 | setTimeout |
渲染任务 | 浏览器自动调度 | 微任务之后、宏任务之前 | requestAnimationFrame |
✨ 记忆口诀
"同步先走,微务插队,宏任务排队,循环不累"
(同步 → 微任务 → 渲染 → 宏任务 → 循环...)