欧美亚洲中文,在线国自产视频,欧洲一区在线观看视频,亚洲综合中文字幕在线观看

      1. <dfn id="rfwes"></dfn>
          <object id="rfwes"></object>
        1. 站長(zhǎng)資訊網(wǎng)
          最全最豐富的資訊網(wǎng)站

          node.js事件隊(duì)列有幾個(gè)階段

          node.js事件隊(duì)列有6個(gè)階段:1、“timers”階段;2、“I/O callbacks”階段;3、“idle, prepare”階段;4、“poll”階段;5、“check”階段;6、“close callbacks”階段。

          node.js事件隊(duì)列有幾個(gè)階段

          本教程操作環(huán)境:windows7系統(tǒng)、nodejs 12.19.0版,DELL G3電腦。

          Node里的事件隊(duì)列和瀏覽器中的差異性還是比較大的,但是共同點(diǎn)就是宏任務(wù)和微任務(wù)的機(jī)制,是一樣的,如圖是關(guān)于node的宏任務(wù)與微任務(wù)分類。
          node.js事件隊(duì)列有幾個(gè)階段
          nexttick會(huì)在node的每一次事件開啟時(shí)最先執(zhí)行(微任務(wù)最高優(yōu)先級(jí))。

          而關(guān)于node事件隊(duì)列可分為如下6個(gè)階段:
          node.js事件隊(duì)列有幾個(gè)階段

          1、timers 階段:這個(gè)階段執(zhí)行timer(setTimeout、setInterval)的回調(diào)

          2、I/O callbacks 階段:執(zhí)行一些系統(tǒng)調(diào)用錯(cuò)誤,比如網(wǎng)絡(luò)通信的錯(cuò)誤回調(diào)

          3、idle, prepare 階段:僅node內(nèi)部使用

          4、poll 階段:獲取新的I/O事件, 適當(dāng)?shù)臈l件下node將阻塞在這里

          5、check 階段:執(zhí)行 setImmediate() 的回調(diào)

          6、close callbacks 階段:執(zhí)行 socket 的 close 事件回調(diào)

          我們重點(diǎn)看timers、poll、check這3個(gè)階段就好,因?yàn)槿粘i_發(fā)中的絕大部分異步任務(wù)都是在這3個(gè)階段處理的。

          timers 階段

          timers 是事件循環(huán)的第一個(gè)階段,Node 會(huì)去檢查有無已過期的timer,如果有則把它的回調(diào)壓入timer的任務(wù)隊(duì)列中等待執(zhí)行,事實(shí)上,Node 并不能保證timer在預(yù)設(shè)時(shí)間到了就會(huì)立即執(zhí)行,因?yàn)镹ode對(duì)timer的過期檢查不一定靠譜,它會(huì)受機(jī)器上其它運(yùn)行程序影響,或者那個(gè)時(shí)間點(diǎn)主線程不空閑。比如下面的代碼,setTimeout() 和 setImmediate() 的執(zhí)行順序是不確定的。

          setTimeout(() => {   console.log('timeout')}, 0)setImmediate(() => {   console.log('immediate')})

          如上段代碼是個(gè)大坑,node無法確定每次事件隊(duì)列建立完畢的具體時(shí)間,可能這一次是5ms(timer被壓入棧,在第二輪才會(huì)執(zhí)行),下一次是1ms(timer在第一輪就被捕獲執(zhí)行了)。因此輸出結(jié)果順序不確定,這也是具體原因,而當(dāng)嵌套一個(gè)異步的操作把他們包裹起來,就會(huì)100%保證immediate先執(zhí)行。

          fs.readFile('./index.html',(err,result)=>{ 	setTimeout(() => { 	  console.log('timeout') 	}, 0) 	 	setImmediate(() => { 	  console.log('immediate') 	})})

          這是因?yàn)橛捎谠诘谝惠單床蹲皆趖imer,所以直接到了poll階段進(jìn)行io的回調(diào)捕捉,當(dāng)io結(jié)束后進(jìn)入check階段,就會(huì)執(zhí)行immediate,而timeout會(huì)在第二輪最開始的timer執(zhí)行。

          poll 階段

          poll 階段主要有2個(gè)功能:
          1.處理 poll 隊(duì)列的事件
          2.當(dāng)有已超時(shí)的 timer,執(zhí)行它的回調(diào)函數(shù)

          even loop將同步執(zhí)行poll隊(duì)列里的回調(diào),直到隊(duì)列為空或執(zhí)行的回調(diào)達(dá)到系統(tǒng)上限(上限具體多少未詳),接下來even loop會(huì)去檢查有無預(yù)設(shè)的setImmediate(),分兩種情況:

          1.若有預(yù)設(shè)的setImmediate(), event loop將結(jié)束poll階段進(jìn)入check階段,并執(zhí)行check階段的任務(wù)隊(duì)列
          2.若沒有預(yù)設(shè)的setImmediate(),event loop將阻塞在該階段等待

          注意一個(gè)細(xì)節(jié),沒有setImmediate()會(huì)導(dǎo)致event loop阻塞在poll階段,這樣之前設(shè)置的timer豈不是執(zhí)行不了了?所以咧,在poll階段event loop會(huì)有一個(gè)檢查機(jī)制,檢查timer隊(duì)列是否為空,如果timer隊(duì)列非空,event loop就開始下一輪事件循環(huán),即重新進(jìn)入到timer階段。

          check 階段

          setImmediate()的回調(diào)會(huì)被加入check隊(duì)列中, 從event loop的階段圖可以知道,check階段的執(zhí)行順序在poll階段之后。

          小結(jié)

          node中每一輪大的事件循環(huán)中劃分出了六個(gè)場(chǎng)景,每個(gè)場(chǎng)景需要按順序執(zhí)行,比瀏覽器會(huì)更加細(xì)化,并且在每一個(gè)階段都會(huì)進(jìn)行宏任務(wù)和微任務(wù)的處理,這是比較特殊的一點(diǎn)。

          1、Node.js 的事件循環(huán)分為6個(gè)階段

          2、瀏覽器和Node 環(huán)境下,microtask 任務(wù)隊(duì)列的執(zhí)行時(shí)機(jī)不同

          Node.js中,microtask 在事件循環(huán)的各個(gè)階段之間執(zhí)行

          瀏覽器端,microtask 在事件循環(huán)的 macrotask 執(zhí)行完之后執(zhí)行

          3、遞歸的調(diào)用process.nextTick()會(huì)導(dǎo)致I/O starving,官方推薦使用setImmediate()

          4、每個(gè)事件階段nexttick在微任務(wù)中的優(yōu)先級(jí)是最高的。

          贊(0)
          分享到: 更多 (0)
          網(wǎng)站地圖   滬ICP備18035694號(hào)-2    滬公網(wǎng)安備31011702889846號(hào)