【问题标题】:Why does the Node.js event loop require multiple phases?为什么 Node.js 事件循环需要多个阶段?
【发布时间】:2019-01-15 22:40:29
【问题描述】:

阅读了几十篇描述 Node.js 事件循环的文章和文档,比如 Node.js 自己提供的一篇:https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/

我简直无法理解:为什么事件循环需要多个阶段,每个阶段都有自己的回调队列?

所有的文档和文章都以“这个阶段做某事并执行用 X 或 Y 设置的回调”来描述循环的各个阶段,但从未真正解释过为什么首先需要这些单独的队列。

为什么setTimeout()setImmediate() 的回调或套接字关闭需要在与执行绝大多数回调的轮询阶段不同的时间点执行?

如果轮询阶段的回调队列在进入下一阶段之前已经耗尽,为什么不让一个队列因其他阶段执行的任何非队列相关操作而中断?

【问题讨论】:

  • 几乎需要 Node.js 团队的长期成员来回答这个问题。 (已知一两个会发布 SO 答案。)
  • 可能存在一些优先级问题,但这些不同的队列看起来更像是实现细节,而不是有意义的设计选择(通常有充分的理由将队列分开,例如便于清理)。
  • 我是 Node 核心,我猜对了,但我也很感兴趣(出于历史原因)。我将在 node-dev 中 ping 核心,看看我们是否能得到答案:)
  • 一般来说,我从来没有遇到过不需要某种优先通道的排队系统。 :-)
  • @BenjaminGruenbaum 你得到答案了吗?

标签: javascript node.js loops callback queue


【解决方案1】:

不必是这样的。一切都可能在一个队列中,但可以肯定的是,NodeJS 的创建者有一些理由按照他们的方式去做。我们知道 Javascript 是单线程的。所以,如果你说你想让一个事件在 5 秒后发生,那么就没有其他线程来确保这个事件真的在指定的时间运行。另一方面,不可能事先确定给定函数是否会持续 0.1 秒,即 4.5 秒。

因此,即使他们不必像以前那样做,将计时器功能放在高优先级队列中并首先处理它们也有客观的好处。这样系统就会知道是否应该紧急执行某事,并且可以在处理其他所有事情之前紧急执行它。此外,系统将知道在执行下一个计时器事件之前还有多少时间。

待处理的回调是系统所等待的,因此它非常有用,而且将其放入第二个队列有客观的好处,该队列的优先级低于计时器,但高于其他事物。

正如我们在轮询部分看到的,它的行为取决于计时器队列的状态。

check 会执行 poll 阶段指定的一些事件。

关闭回调将在适当的情况下处理回调中断。

因此,我们可以从文章中理解所有这些方面,尽管我必须承认,它需要比人们期望的更多的思考来阐明它。

简而言之,它不必按照它的工作方式工作。有无数种可能的方法与此方法不同并且会很有效。

【讨论】:

    【解决方案2】:

    这个视频link 可能比任何其他关于回调的材料都描述得更好。 回答不同阶段的问题,就拿这个例子,按照官方文档link进行模拟,以获得更好的画面。

    setTimeout(function(){
            console.log("the first block after 3 sec.");
    },3000);
    console.log("Hello after 3000");
    setTimeout(function(){
            console.log("the second block after 1 sec.");
    },1000);
    console.log("Hello after 1000");
    setTimeout(function(){
            console.log("the third block after 2 sec.");
    },2000);
    console.log("Hello after 2000");
    setTimeout(function(){
            console.log("the last block after 0 sec.");
    },0);
    console.log("End after 0");
    

    【讨论】:

      猜你喜欢
      • 2022-01-08
      • 2015-10-13
      • 1970-01-01
      • 1970-01-01
      • 2019-02-20
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      • 1970-01-01
      相关资源
      最近更新 更多