深入理解 Node.js 事件循环机制
Node.js 的事件循环是其核心特性之一,理解它对于编写高效的异步代码至关重要。
什么是事件循环?
事件循环是 Node.js 实现非阻塞 I/O的关键机制。它允许 Node.js 在单线程中执行大量 I/O 操作而不会阻塞。
事件循环的六个阶段
1. Timers(定时器)
setTimeout()和setInterval()的回调函数在这里执行- 指定的时间是从事件循环开始计算的
2. Pending Callbacks
- 执行一些推迟到下一个循环迭代的 I/O 回调
- 例如某些 TCP 错误
3. Idle, Prepare
- 内部使用
4. Poll(轮询)
- 获取新的 I/O 事件
- 执行
fs.readFile()等操作的回调 - 如果没有定时器,可能会在这里阻塞
5. Check
- 执行
setImmediate()的回调
6. Close Callbacks
- 执行
socket.on('close', ...)等关闭回调
实际例子
console.log('1');
setTimeout(() => console.log('2'), 0);
setImmediate(() => console.log('3'));
console.log('4');
输出顺序:1 → 4 → 3 → 2(通常)
这是因为 setImmediate() 在 check 阶段执行,而 setTimeout() 在 timers 阶段执行。
最佳实践
- 避免阻塞事件循环:使用异步操作,同步代码会阻塞
- 合理使用定时器:理解
setTimeout(fn, 0)不会立即执行 - 区分 setImmediate 和 process.nextTick:
process.nextTick()在当前操作完成后立即执行setImmediate()在下一个事件循环阶段执行
总结
掌握事件循环机制能帮助你:
- 更好地理解异步代码执行顺序
- 编写更高效的代码
- 调试复杂的异步问题
希望这篇文章对你有帮助!如有疑问,欢迎在评论区讨论。