“事件循环阶段”之间的区别,例如“I / O回调”和“轮询”

时间:2018-03-27 07:49:40

标签: node.js event-loop single-threaded

在阅读Node.js的I/O callback机制时,我无法理解两个阶段pollevent loop之间的区别。

我的理解如下。如果错误请更正:

例如,当我们尝试异步读取文件时,poll阶段会收到读取文件的I / O指令(因此,读取文件是在轮询阶段发生的吗?)并添加callback fs.readFile()I/O callback阶段{fs.readFile的回调在I/O callback阶段执行?)。

1 个答案:

答案 0 :(得分:0)

我认为没有人能比Node.js official docs更好地解释这一点。

一些关键部分:

  

什么是事件循环?

     

事件循环允许Node.js执行非阻塞I / O.   操作 - 尽管JavaScript是单线程的 - 通过   尽可能将操作卸载到系统内核。

     

由于大多数现代内核都是多线程的,因此它们可以处理多个内核   在后台执行的操作。当其中一个操作   完成后,内核告诉Node.js以便进行相应的回调   可以添加到轮询队列中以最终执行。我们' 11   在本主题后面进一步详细解释。

     

事件循环说明

     

当Node.js启动时,它初始化事件循环,处理   提供输入脚本(或放入REPL,未包含在内   此文档)可能会进行异步API调用,计划定时器或   调用process.nextTick(),然后开始处理事件循环。

     

下图显示了事件循环的简要概述   操作顺序。

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

注意:每个方框都将被称为a   &#34;相&#34;事件循环。

     

每个阶段都有一个要执行的回调FIFO队列。而每个阶段   通常,当事件循环进入时,它以自己的方式是特殊的   给定阶段,它将执行特定于该阶段的任何操作,   然后在该阶段的队列中执行回调,直到队列结束   已用尽或已执行最大回调数。当。。。的时候   队列已用尽或达到回调限制,事件   循环将移至下一阶段,依此类推。

     

由于这些操作中的任何一个都可能安排更多操作和新操作   在轮询阶段处理的事件由内核排队,轮询   在处理轮询事件时,事件可以排队。作为一个   结果,长时间运行的回调可以允许轮询阶段运行很多   超过计时器的阈值。查看计时器和民意调查部分   更多细节。

     

注意:Windows和Windows之间存在轻微差异   Unix / Linux实现,但这对此并不重要   示范。最重要的部分在这里。实际上有   七个或八个步骤,但我们关心的那些 - Node.js   实际使用 - 是上面那些。

     

阶段概述

     

计时器:此阶段执行setTimeout()和调度的回调   的setInterval()。 I / O回调:执行几乎所有回调   关闭回调的例外,由计时器安排的回调,和   setImmediate()。空闲,准备:仅在内部使用。民意调查:检索   新的I / O事件;节点将在适当时阻止此处。校验:   这里调用setImmediate()回调函数。关闭回调:例如   socket.on(&#39; close&#39;,...)。在每次运行事件循环之间,Node.js   检查它是否在等待任何异步I / O或定时器并关闭   如果没有,那就干净利落。