标准答案
- timers 阶段处理到期的 setTimeout 和 setInterval 回调,但延迟值不是精确执行时间。
- poll 阶段处理多数 I/O 回调,并可能等待新的 I/O;check 阶段处理 setImmediate。
- close callbacks 处理部分句柄关闭事件,pending callbacks 处理特定系统回调。
- 每个阶段之间会处理微任务,因此 Promise 和 process.nextTick 可能插入宏任务之间。
题目解析
事件循环按 timers、pending callbacks、poll、check 和 close callbacks 等阶段推进,但具体回调何时可执行还取决于 I/O 是否就绪、当前阶段和运行时版本。setTimeout(0) 只表示最小延迟,不是立即执行。
Promise 微任务和 process.nextTick 会插入阶段之间,并可能优先于下一轮 I/O。事件循环“单线程”不代表所有回调严格按照源码出现顺序执行。
回答顺序题要说明运行条件,并用实际事件循环延迟和 I/O 测试验证。长时间 nextTick、Promise 或同步回调会让 poll 和 timers 饥饿。
常见误区
- 误区:认为事件循环只有一个队列。改正:区分各阶段、微任务和 nextTick 队列及其调度边界。
- 误区:认为 setTimeout(0) 立即执行。改正:它只表示计时器到期后的最早机会,仍会受当前负载和阶段影响。
- 误区:忽略微任务可能长期占住事件循环。改正:限制递归调度和单次执行时间,监控 event loop delay。