Node学习笔记(3) - Eventloop和事件队列

什么是事件循环(Eventloop)

官网是这样描述的

事件循环是 Node.js 处理非阻塞 I/O 操作的机制——尽管 JavaScript 是单线程处理的——当有可能的时候,它们会把操作转移到系统内核中去。
既然目前大多数内核都是多线程的,它们可在后台处理多种操作。当其中的一个操作完成的时候,内核通知 Node.js 将适合的回调函数添加到 轮询 队列中等待时机执行。

事件循环有哪些阶段

  • 定时器:本阶段执行已经被 setTimeout() 和 setInterval() 的调度回调函数。
  • 待定回调:执行延迟到下一个循环迭代的 I/O 回调。
  • idle, prepare:仅系统内部使用。
  • 轮询:检索新的 I/O 事件;执行与 I/O 相关的回调(几乎所有情况下,除了关闭的回调函数,那些由计时器和 setImmediate() 调度的之外),其余情况 node 将在适当的时候在此阻塞。
  • 检测:setImmediate() 回调函数在这里执行。
  • 关闭的回调函数:一些关闭的回调函数,如:socket.on(‘close’, …)

一个6个阶段,每个阶段都会有类似于队列的概念

另外:
每个阶段都会检查是否有 process.nextTick 任务,如果有,全部执行
检查是否有microtask,如果有,全部执行

Timer

回调都被保存在最小堆中,如果符合条件就拿出来执行, 直到遇到一个不符合条件或者队列空了, 才结束 Timer
每次进入 Timer Phase 的时候都会保存一下当时的系统时间,然后只要看上述最小堆中的回调函数设置的启动时间是否超过进入 Timer Phase 时保存的时间, 如果超过就拿出来执行
Nodejs 为了防止某个 Phase 任务太多, 导致后续的 Phase 发生饥饿的现象, 所以消息循环的每一个迭代(iterate) 中, 每个 Phase 执行回调都有个最大数量. 如果超过数量的话也会强行结束当前 Phase 而进入下一个 Phase

Pending I/O(待定回调)

这一阶段是执行 fs.read, socket 等 IO 操作的回调函数, 同时也包括各种 error 的回调

Poll(轮询)

它首先会判断后面的 Check Phase 以及 Close Phase 是否还有等待处理的回调。如果有, 则不等待, 直接进入下一个 Phase。
如果没有,会在一段时间后进入下一个阶段。

Check(检测)

只处理 setImmediate 的回调函数

常见问题

  1. setTimeout(…, 0) vs. setImmediate

setTimeout(…, 0)vs. setImmediate 到底谁快?

// index.js
setImmediate(() => console.log(2))
setTimeout(() => console.log(1))

答案: 可能是 1 2, 也可能是 2 1

setImmediate() 设计为一旦在当前 轮询 阶段完成, 就执行脚本。
setTimeout() 在最小阈值(ms 单位)过后运行脚本

当执行到 Timer Phase 时, 会发生两种可能. 因为每一轮迭代刚刚进入 Timer Phase 时会取系统时间保存起来, 以 ms(毫秒) 为最小单位.
如果 Timer Phase 中回调预设的时间 > 消息循环所保存的时间, 则执行 Timer Phase 中的该回调. 这种情况下先输出 1, 直到 Check Phase 执行后,输出2.总的来说, 结果是 1 2.
如果运行比较快, Timer Phase 中回调预设的时间可能刚好等于消息循环所保存的时间, 这种情况下, Timer Phase 中的回调得不到执行, 则继续下一个 Phase. 直到 Check Phase, 输出 2. 然后等下一轮迭代的 Timer Phase, 这时的时间一定是满足 Timer Phase 中回调预设的时间 > 消息循环所保存的时间 , 所以 console.log(1) 得到执行, 输出 1. 总的来说, 结果就是 2 1.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值