【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
相似问题