check 阶段的 setImmediate 在 poll 阶段的 readFile 之前执行
来源:7-3 从 libuv 源码来理解 Event Loop 的 6 个阶段

ShineTech
2018-02-09
我的是 mac 环境 node 8.9.3, 代码与老师一致,但是打印的执行顺序中,属于第三阶段check的setImmediate 在 属于 第二阶段IO操作的readFile 之前执行。。。这就让我很困惑了。
const { readFile } = require('fs'); const EventEmitter = require('events'); const eve = new EventEmitter(); eve.on('hi', () => { console.log('hi') }) setTimeout(() => { console.log('exec the 1st setTimeout timer') }, 0) setTimeout(() => { console.log('exec the 2nd setTimeout timer') }, 50) setTimeout(() => { console.log('exec the 3rd setTimeout timer') }, 100) readFile('./package.json', 'utf-8', data => { console.log('exec the 1st read file') }) readFile('./package.json', 'utf-8', data => { console.log('exec the 2nd read file') }) setImmediate(() => { console.log('exec the 1st setImmediate') }) Promise.resolve().then(() => { process.nextTick(() => { console.log('exec the 2nd nextTick') }) eve.emit('hi') console.log('exec the 1st promise') }) .then(() => { console.log('exec the 2nd promise') }) process.nextTick(() => { console.log('exec the 1st nextTick') })
写回答
2回答
-
这个结果不一样的原因,在于 readfile 这里的处理,readfile 也就是 IO 是不稳定的,执行时间不等,导致它如果没 ready,那么timer 后就会进入到 check 执行 setImmediate,就是你这种结果,如果 IO ready,那么就是视频中的效果,这就是 Nodejs 里面 IO 魔性的地方,你可以把这个文件放到 /test 目录下,然后把 ./package.json 路径改成 ../package.json,多执行几次,会发现结果并不总是一致的,原因就在于 eventloop 转起来的时候,readfile 是否 ready,timer 是否到期进栈,这两个不确定因素会导致 setImmediate 会不会紧挨着 setTimeout 执行
122018-02-12 -
慕粉3563954
2019-07-30
找到答案了
00
相似问题