JS事件循环混淆

JS event Loop confuse

我是 JS 事件循环的新手,我想知道是否有人可以给我简要介绍一下 js 引擎 运行 这个:

function start(){
  setTimeout(function(){
    console.log("Timeout")
  }, 0)
  setImmediate(function(){
    console.log("Immediate")
  })
  process.nextTick(function(){
    console.log("next tick")
  })
}

结果是:

next tick
Timeout
Immediate

我想当 JS 引擎 运行 是这个时,

  1. 它解析脚本,设置Timer,设置Immediate,设置nextTick队列,然后进入POLL阶段,检查那里是否有任何队列(在这种情况下没有)
  2. 在进入 CHECK 阶段之前,运行s nextTick 队列,打印 "next tick".
  3. 进入CHECK阶段,运行立即队列,打印"Immediate"
  4. 循环回到TIMER阶段,打印"Timeout"

我的困惑是为什么 setTimeout 在 Immediate 之前打印出来?

PS,

我把Timeout delay从0设置到3以上之后,那么顺序就是:

next tick
Immediate
Timeout

但这还是不能解释为什么之前的JS事件循环顺序运行s.

请问有没有遗漏什么?

setImmediate 将函数排在任何 I/O、事件、事件队列中已经存在的回调后面。因此,在这种情况下 setTimeout 已经在队列中。

我觉得你应该再读一遍https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/。它可以回答您所有的问题。我引用上述文件中的以下几行

setImmediate() 与 setTimeout()

setImmediatesetTimeout() 相似,但根据调用时间的不同表现不同。

setImmediate() 旨在在当前轮询阶段完成后执行脚本。 setTimeout() 将脚本安排为 运行 在以毫秒为单位的最小阈值过去后。

计时器的执行顺序将根据调用它们的上下文而有所不同。

理解process.nextTick()

process.nextTick() 在技术上不是事件循环的一部分。相反,nextTickQueue 将在当前操作完成后处理,而不管事件循环的当前阶段如何。

回顾我们的图表,任何时候您在给定阶段调用 process.nextTick(),传递给 process.nextTick() 的所有回调都将在事件循环继续之前得到解决。这可能会造成一些糟糕的情况,因为它允许您通过递归 process.nextTick() 调用来 "starve" 您的 I/O,这会阻止事件循环到达轮询阶段。