JavaScript 的事件循环机制是其单线程执行模型的核心。
1. 事件循环基本模型
2. 完整事件循环流程
3. 核心概念定义
| 概念 | 描述 | 常见API |
|---|---|---|
| 执行栈 | JavaScript 主线程按顺序执行代码的调用栈 | - |
| 宏任务队列 | 存放待执行的"粗粒度"任务,每次事件循环处理一个宏任务 | setTimeout, setInterval, I/O, UI渲染 |
| 微任务队列 | 存放待执行的"细粒度"任务,必须在当前宏任务结束后立即全部执行 | Promise.then, MutationObserver, queueMicrotask |
| UI渲染时机 | 在微任务队列清空后,下一个宏任务前执行 | requestAnimationFrame |
4. 代码执行过程分解
示例代码:
console.log('A');
setTimeout(() => {
console.log('B');
}, 0);
Promise.resolve().then(() => {
console.log('C');
});
console.log('D');执行步骤:
同步阶段:
执行栈顺序执行:
A D- 注册宏任务
B到宏任务队列 - 注册微任务
C到微任务队列
微任务阶段:
执行所有微任务:
C
宏任务阶段:
从宏任务队列取出第一个任务:
B
最终输出:
A
D
C
B5. Node.js 与浏览器的差异
| 环境 | 同步代码执行机制 | 特殊案例 |
|---|---|---|
| 浏览器 | 直接执行,不属于任务队列 | <script> 整体是初始宏任务 |
| Node.js | 直接执行,不属于任务队列 | process.nextTick 优先级高于微任务 |
6. 总结
- 执行栈(Execution Context Stack):所有同步任务都在主线程上执行,形成一个执行栈。
- 任务队列(Task Queue):包含宏任务队列和微任务队列,用于存放异步任务的回调。
事件循环(Event Loop):负责在执行栈为空时,从任务队列中取出任务执行,确保异步任务被及时处理。
- 同步代码 ≠ 宏任务
- 事件循环从宏任务队列取任务,但同步代码直接执行
- 微任务在当前同步代码执行完后立即执行
- UI渲染发生在微任务队列清空后、下一个宏任务前
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。