请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

【7-4】事件循环中第二阶段异步IO和第三阶段check的执行顺序的问题

//img1.sycdn.imooc.com//szimg/5ac3503000019a2411161056.jpg

scott好,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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先执行呢?同样的,后面的一个框也是这样的问题,我没有想明白这是为什么?

正在回答 回答被采纳积分+3

插入代码

2回答

Scott 2018-04-05 12:28:23

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 篇吧,更全,通过这个来理解这个执行结果,会更全面一些

0 回复 有任何疑惑可以回复我~
提问者 慕名小白 2018-04-04 09:26:17

再来补充一下环境,node版本是v8.4.0,把node版本切换到v8.9.4执行结果还是一样的

0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号