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 引擎 运行 是这个时,
- 它解析脚本,设置Timer,设置Immediate,设置nextTick队列,然后进入POLL阶段,检查那里是否有任何队列(在这种情况下没有)
- 在进入 CHECK 阶段之前,运行s nextTick 队列,打印 "next tick".
- 进入CHECK阶段,运行立即队列,打印"Immediate"
- 循环回到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()
setImmediate
和 setTimeout()
相似,但根据调用时间的不同表现不同。
setImmediate()
旨在在当前轮询阶段完成后执行脚本。
setTimeout()
将脚本安排为 运行 在以毫秒为单位的最小阈值过去后。
计时器的执行顺序将根据调用它们的上下文而有所不同。
理解process.nextTick()
process.nextTick()
在技术上不是事件循环的一部分。相反,nextTickQueue
将在当前操作完成后处理,而不管事件循环的当前阶段如何。
回顾我们的图表,任何时候您在给定阶段调用 process.nextTick()
,传递给 process.nextTick()
的所有回调都将在事件循环继续之前得到解决。这可能会造成一些糟糕的情况,因为它允许您通过递归 process.nextTick()
调用来 "starve" 您的 I/O,这会阻止事件循环到达轮询阶段。
我是 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 引擎 运行 是这个时,
- 它解析脚本,设置Timer,设置Immediate,设置nextTick队列,然后进入POLL阶段,检查那里是否有任何队列(在这种情况下没有)
- 在进入 CHECK 阶段之前,运行s nextTick 队列,打印 "next tick".
- 进入CHECK阶段,运行立即队列,打印"Immediate"
- 循环回到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()
setImmediate
和 setTimeout()
相似,但根据调用时间的不同表现不同。
setImmediate()
旨在在当前轮询阶段完成后执行脚本。
setTimeout()
将脚本安排为 运行 在以毫秒为单位的最小阈值过去后。
计时器的执行顺序将根据调用它们的上下文而有所不同。
理解process.nextTick()
process.nextTick()
在技术上不是事件循环的一部分。相反,nextTickQueue
将在当前操作完成后处理,而不管事件循环的当前阶段如何。
回顾我们的图表,任何时候您在给定阶段调用 process.nextTick()
,传递给 process.nextTick()
的所有回调都将在事件循环继续之前得到解决。这可能会造成一些糟糕的情况,因为它允许您通过递归 process.nextTick()
调用来 "starve" 您的 I/O,这会阻止事件循环到达轮询阶段。