3.3.2 观察者

30 阅读2分钟

这一子节承接事件循环,解释了事件循环是如何“知道”有事件发生的——答案就是**观察者(Observer)**机制。

什么是观察者?

在Node/libuv中,每一种可能产生异步事件的资源(网络I/O、文件I/O、定时器、子进程等)都有对应的观察者
观察者本质是一个结构体,记录了:

  • 当前感兴趣的事件类型(如可读、可写、定时到期)
  • 对应的回调函数(或回调队列)
  • 所属的事件循环

每个阶段(phase)都有自己的观察者队列:

  • timers阶段 → timer观察者(setTimeout/setInterval)
  • poll阶段 → I/O观察者(网络、文件等)
  • check阶段 → immediate观察者(setImmediate)
  • pending callbacks、close等也有自己的

事件循环与观察者的关系

事件循环每进入一个阶段,就:

  1. 检查该阶段是否有活跃的观察者
  2. 如果有,调用底层API等待这些观察者就绪(如epoll_wait、GetQueuedCompletionStatus)
  3. 一旦有观察者就绪,执行其关联的回调

作者用一个生动比喻:

事件循环像一个巡警,每到一个“岗亭”(阶段),就问:“你们这组观察者有没有动静?”
poll阶段的岗亭最大,里面站着网络和文件观察者,他们负责盯着底层系统调用。

关键点

  • 观察者是事件驱动的核心:没有观察者,事件循环就空转或退出。
  • 每个I/O请求都会创建一个观察者(或复用),注册到poll阶段。
  • process.nextTick 和 Promise 的 microtask 不依赖观察者,而是直接挂在事件循环当前轮询上(优先级更高)。

下面是经典的“事件循环各阶段观察者示意图”和“观察者注册流程图”(几乎所有读者笔记都会画这两张):

这一子节短小精悍,但至关重要——它把“事件循环”从抽象概念变成了“有观察者在站岗”的具体机制。