【7-4】事件循环中第二阶段异步IO和第三阶段check的执行顺序的问题
来源:7-4 设计一个测试用例来验证自己对事件循环的理解
慕名小白
2018-04-03

scott好,
const { readFile, readFileSync } = require('fs')
setImmediate(() => console.log('[阶段3.immediate] immediate 回调1'))
setImmediate(() => console.log('[阶段3.immediate] immediate 回调2'))
setImmediate(() => console.log('[阶段3.immediate] immediate 回调3'))
Promise.resolve()
.then(() => {
console.log('[...等待切入下一个阶段] promise 回调 1')
setImmediate(() => console.log('[阶段3.immediate] promise 回调1 增加的 immediate 回调4'))
})
readFile('../package.json', 'utf-8', data => {
console.log('[阶段2...IO 回调] 读文件回调1')
readFile('../package-lock.json', 'utf-8', data => {
console.log('[阶段2...IO 回调] 读文件回调2')
setImmediate(() => console.log('[阶段3.immediate] 读文件回调2 增加的 immediate 回调4'))
})
setImmediate(() => {
console.log('[阶段3.immediate] immediate 回调5')
Promise.resolve()
.then(() => {
console.log('[...等待切入下一个阶段] promise 回调 2')
process.nextTick(() => {
console.log('[...待切入下一个阶段] promise 回调2增加的 nextTick 回调5')
})
})
.then(() => {
console.log('[...等待切入下一个阶段] promise 回调 3')
})
})
setImmediate(() => {
console.log('[阶段3.immediate] immediate 回调6')
process.nextTick(() => {
console.log('[...待切入下一个阶段] immediate 回调6 nextTick 回调7')
})
console.log('[...待切入下一个阶段] 这块正在同步阻塞的读一个大文件')
const video = readFileSync('../package-lock.json', 'utf-8')
process.nextTick(() => {
console.log('[...待切入下一个阶段] immediate 回调6 nextTick 回调8')
})
readFile('../package.json', 'utf-8', data => {
console.log('[阶段2...IO回调] 读文件回调3')
setImmediate(() => console.log('[阶段3.immediate] 读文件回调3 增加的 immediate 回调6'))
setTimeout(() => console.log('[阶段1...定时器] 读文件回调3 增加的 定时器回调8'), 0)
})
})
process.nextTick(() => {
console.log('[...待切入下一个阶段] 读文件 回调1 增加的 nextTick 回调6')
})
setTimeout(() => console.log('[阶段1...定时器] 定时器 回调5'), 0)
setTimeout(() => console.log('[阶段1...定时器] 定时器 回调6 '), 0)
})
setTimeout(() => console.log('[阶段1...定时器] 定时器 回调1'), 0)
setTimeout(() => {
console.log('[阶段1...定时器] 定时器 回调2')
process.nextTick(() => {
console.log('[...待切入下一个阶段] nextTick 回调5')
})
}, 0)
setTimeout(() => console.log('[阶段1...定时器] 定时器 回调3'), 0)
setTimeout(() => console.log('[阶段1...定时器] 定时器 回调4'), 0)
process.nextTick(() => console.log('[...待切入下一个阶段] nextTick 回调1'))
process.nextTick(() => {
console.log('[...待切入下一个阶段] nextTick 回调2')
process.nextTick(() => console.log('[...待切入下一个阶段] nextTick 回调4'))
})
process.nextTick(() => console.log('[...待切入下一个阶段] nextTick 回调3'))在执行timers阶段70行~79行中的这个打印的setTimout中有一个nextTick([...待切入下一个阶段] nextTick 回调5,执行完这个后
就该进入到第二阶段,但是为什么图中,我画框的打印中,第三阶段的immediate会比异步IO先执行呢?同样的,后面的一个框也是这样的问题,我没有想明白这是为什么?
写回答
2回答
-
Scott
2018-04-05
IO 是事件循环中,最不可控的一个环节了,它与 immediate 的关系,从你贴的图上看,也是成立的,immediate 是在 ready 阶段来执行,而 IO 是在之前,但这个之前只是逻辑上的之前,在 Next tick 执行完毕之后,immediate 往往会比 IO 这个先执行。
课程的这个示例是比较极端的形式,我建议你大概知道这阶段后,来看下更深入的一个时间循环探究,是好几篇文章来讲述:
https://www.zcfy.cc/article/event-loop-and-the-big-picture-nodejs-event-loop-part-1-3566.html?t=new
这是中文版,英文版的系列是 5 篇吧,更全,通过这个来理解这个执行结果,会更全面一些
00 -
慕名小白
提问者
2018-04-04
再来补充一下环境,node版本是v8.4.0,把node版本切换到v8.9.4执行结果还是一样的
00
相似问题