浅析Js Event Loop

5次阅读

共计 1441 个字符,预计需要花费 4 分钟才能阅读完成。

什么是 Event Loop?
官网解释

个人理解是 js 的单线程是他的任务栈是单线程,但他处理异步 i / o 的方法是依赖 libuv 开启线程池去处理,完成之后任务加到 poll queue 里,然后等任务栈的任务为空或事件到达阀值时,把 poll queue 和定时器的任务加到任务栈里,继续这个循环,这就是大体上的 js 的 Event Loop。
结构
┌───────────────────────────┐
┌─>│ timers │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ pending callbacks │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ idle, prepare │
│ └─────────────┬─────────────┘ ┌───────────────┐
│ ┌─────────────┴─────────────┐ │ incoming: │
│ │ poll │<─────┤ connections, │
│ └─────────────┬─────────────┘ │ data, etc. │
│ ┌─────────────┴─────────────┐ └───────────────┘
│ │ check │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
└──┤ close callbacks │
└───────────────────────────┘
timer:定时任务,当到达阀值时,他不会立即执行,会等待任务栈的任务会阻塞他。
pending callbacks:此阶段执行某些系统操作(例如 TCP 错误类型)的回调。例如,如果 TCP 套接字在尝试连接时收到,则某些 *nix 系统希望等待报告错误。这将排队等待在挂起的回调阶段执行。
pull: 这个阶段有两个主要功能:计算它应该阻塞和轮询 I / O 的时间,然后 处理轮询队列中的事件。当事件循环进入轮询阶段并且没有计划定时器时,将发生以下两种情况之一:
如果轮询队列不为空,则事件循环将遍历其同步执行它们的回调队列,直到队列已用尽,或者达到系统相关的硬限制。
如果轮询队列为空,则会发生以下两种情况之一:
如果脚本已执行 setImmediate,则事件循环将结束 poll 阶段并继续执行 check 阶段以执行这些调度脚本。
如果脚本没有执行 setImmediate,事件循环将等待回调被添加到 poll queue 中,然后立即执行。
一旦 poll queue 为空事件循环将检查 timer,如果一个或多个定时器准备就绪,事件循环将回绕到 timer 阶段以执行那些 timer 的回调。
check 此阶段允许人员在轮询阶段完成后立即执行回调。如果轮询阶段变为空闲并且存在 setImmediate 任务,那么事件循环直接跳到 check 执行而不是阻塞在 poll 阶段等待回调被加入。
setImmediate 实际上是一个特殊的计时器,它在事件循环的一个单独阶段运行。它使用 libuv API 来调度在轮询阶段完成后执行的回调。
close callbacks
如果 socket 或 handle 突然关闭(例如 socket.destroy()),则该 ‘close’ 事件将在此阶段发出。否则它将通过发射 process.nextTick()。
引用:
https://nodejs.org/en/docs/gu…

正文完
 0