乐趣区

libuv核心开发者眼中的Nodejs-Event-loop

文中提到的 event loop 均是指 node.js 中的。
一般网络上讲解的 event loop,都会出现这张图:

libuv 的核心开发者 Bert Belder 觉得不太正确,他认为下面这张图更接近 libuv 的 event loop 原理,但也不完全正确:

他认为真正的 event loop 应该差不多是这样的:



图中左侧分别有入口和出口箭头,入口代表 node js 文件开始执行,出口代表执行完成;
黄色 JS 方块代表同步 JS 的执行;
其他图标分别对应 node.js 官网中 event loop 的讲解 [1]

 ┌───────────────────────────┐
┌─>│           timers          │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │     pending callbacks     │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │       idle, prepare       │
│  └─────────────┬─────────────┘      ┌───────────────┐
│  ┌─────────────┴─────────────┐      │   incoming:   │
│  │           poll            │<─────┤  connections, │
│  └─────────────┬─────────────┘      │   data, etc.  │
│  ┌─────────────┴─────────────┐      └───────────────┘
│  │           check           │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
└──┤      close callbacks      │
   └───────────────────────────┘

闹钟图标代表:timers (setTimeout, setInterval)
独角兽图标代表:poll
感叹号图标代表:check (setImmediately)
扫帚图标代表:close callbacks(比如 socket.on(‘close’, callback))

每个图标是一种类型的 callback 任务队列,图标之间都会执行 JS 同步代码;
同步代码中出现异步的 API 时,对一个全局计数器 ref++,然后交给相应图标对应的模块去处理;
处理完成之后放到对应的图标中,同时对全局计数器 ref–;
扫帚图标(close callbacks)之后,如果 ref 为 0,则结束 js 运行,如果大于 0,则继续 loop;

参考来源:
[1] Everything You Need to Know About Node.js Event Loop – Bert Belder
[2] The Node.js Event Loop

退出移动版