Node.js 事件循环:阶段与顺序
深入理解事件循环的六个阶段以及 timers、poll、check 队列的执行顺序。 · 难度:入门 · +15XP
事件循环概览
Node.js 的事件循环是单线程异步的核心机制。它按阶段(phase)运行,每个阶段维护一个回调队列。理解阶段顺序对编写可预测的异步代码至关重要。
六个阶段
- timers:执行
setTimeout和setInterval的回调 - pending callbacks:执行延迟到下一轮循环的 I/O 回调
- idle, prepare:内部使用
- poll:获取新的 I/O 事件,执行 I/O 回调
- check:执行
setImmediate回调 - close callbacks:执行关闭回调(如 socket.on('close'))
关键示例
const fs = require('fs');
setTimeout(() => console.log('timeout'), 0);
setImmediate(() => console.log('immediate'));
fs.readFile(__filename, () => {
console.log('I/O callback');
setTimeout(() => console.log('I/O timeout'), 0);
setImmediate(() => console.log('I/O immediate'));
});
// 输出顺序通常为:
// timeout
// immediate
// I/O callback
// I/O immediate
// I/O timeout
阶段优先级
| 阶段 | 回调示例 | 执行时机 |
|---|---|---|
| timers | setTimeout(fn, 0) | 最早(如果计时器到期) |
| poll | I/O 回调 | timers 之后 |
| check | setImmediate | poll 阶段之后 |
练习提示
修改右侧代码,添加一个 process.nextTick 调用并观察它在哪个阶段之前执行。提示:nextTick 不属于事件循环阶段,它会在每个阶段之间执行。