成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官:說說對 Node.js 中的事件循環(huán)機(jī)制理解?

開發(fā) 前端
在瀏覽器事件循環(huán)中,我們了解到j(luò)avascript在瀏覽器中的事件循環(huán)機(jī)制,其是根據(jù)HTML5定義的規(guī)范來實(shí)現(xiàn)

本文轉(zhuǎn)載自微信公眾號「JS每日一題」,作者灰灰。轉(zhuǎn)載本文請聯(lián)系JS每日一題公眾號。  

一、是什么

在瀏覽器事件循環(huán)中,我們了解到j(luò)avascript在瀏覽器中的事件循環(huán)機(jī)制,其是根據(jù)HTML5定義的規(guī)范來實(shí)現(xiàn)

而在NodeJS中,事件循環(huán)是基于libuv實(shí)現(xiàn),libuv是一個多平臺的專注于異步IO的庫,如下圖最右側(cè)所示:

上圖EVENT_QUEUE 給人看起來只有一個隊(duì)列,但EventLoop存在6個階段,每個階段都有對應(yīng)的一個先進(jìn)先出的回調(diào)隊(duì)列

二、流程

上節(jié)講到事件循環(huán)分成了六個階段,對應(yīng)如下:

  • timers階段:這個階段執(zhí)行timer(setTimeout、setInterval)的回調(diào)
  • 定時器檢測階段(timers):本階段執(zhí)行 timer 的回調(diào),即 setTimeout、setInterval 里面的回調(diào)函數(shù)
  • I/O事件回調(diào)階段(I/O callbacks):執(zhí)行延遲到下一個循環(huán)迭代的 I/O 回調(diào),即上一輪循環(huán)中未被執(zhí)行的一些I/O回調(diào)
  • 閑置階段(idle, prepare):僅系統(tǒng)內(nèi)部使用
  • 輪詢階段(poll):檢索新的 I/O 事件;執(zhí)行與 I/O 相關(guān)的回調(diào)(幾乎所有情況下,除了關(guān)閉的回調(diào)函數(shù),那些由計(jì)時器和 setImmediate() 調(diào)度的之外),其余情況 node 將在適當(dāng)?shù)臅r候在此阻塞
  • 檢查階段(check):setImmediate() 回調(diào)函數(shù)在這里執(zhí)行
  • 關(guān)閉事件回調(diào)階段(close callback):一些關(guān)閉的回調(diào)函數(shù),如:socket.on('close', ...)

每個階段對應(yīng)一個隊(duì)列,當(dāng)事件循環(huán)進(jìn)入某個階段時, 將會在該階段內(nèi)執(zhí)行回調(diào),直到隊(duì)列耗盡或者回調(diào)的最大數(shù)量已執(zhí)行, 那么將進(jìn)入下一個處理階段

除了上述6個階段,還存在process.nextTick,其不屬于事件循環(huán)的任何一個階段,它屬于該階段與下階段之間的過渡, 即本階段執(zhí)行結(jié)束, 進(jìn)入下一個階段前, 所要執(zhí)行的回調(diào),類似插隊(duì)

流程圖如下所示:

在Node中,同樣存在宏任務(wù)和微任務(wù),與瀏覽器中的事件循環(huán)相似

微任務(wù)對應(yīng)有:

  • next tick queue:process.nextTick
  • other queue:Promise的then回調(diào)、queueMicrotask

宏任務(wù)對應(yīng)有:

  • timer queue:setTimeout、setInterval
  • poll queue:IO事件
  • check queue:setImmediate
  • close queue:close事件

其執(zhí)行順序?yàn)椋?/p>

  • next tick microtask queue
  • other microtask queue
  • timer queue
  • poll queue
  • check queue
  • close queue

三、題目

通過上面的學(xué)習(xí),下面開始看看題目

  1. async function async1() { 
  2.     console.log('async1 start'
  3.     await async2() 
  4.     console.log('async1 end'
  5.  
  6. async function async2() { 
  7.     console.log('async2'
  8.  
  9. console.log('script start'
  10.  
  11. setTimeout(function () { 
  12.     console.log('setTimeout0'
  13. }, 0) 
  14.  
  15. setTimeout(function () { 
  16.     console.log('setTimeout2'
  17. }, 300) 
  18.  
  19. setImmediate(() => console.log('setImmediate')); 
  20.  
  21. process.nextTick(() => console.log('nextTick1')); 
  22.  
  23. async1(); 
  24.  
  25. process.nextTick(() => console.log('nextTick2')); 
  26.  
  27. new Promise(function (resolve) { 
  28.     console.log('promise1'
  29.     resolve(); 
  30.     console.log('promise2'
  31. }).then(function () { 
  32.     console.log('promise3'
  33. }) 
  34.  
  35. console.log('script end'

分析過程:

  • 先找到同步任務(wù),輸出script start
  • 遇到第一個 setTimeout,將里面的回調(diào)函數(shù)放到 timer 隊(duì)列中
  • 遇到第二個 setTimeout,300ms后將里面的回調(diào)函數(shù)放到 timer 隊(duì)列中
  • 遇到第一個setImmediate,將里面的回調(diào)函數(shù)放到 check 隊(duì)列中
  • 遇到第一個 nextTick,將其里面的回調(diào)函數(shù)放到本輪同步任務(wù)執(zhí)行完畢后執(zhí)行
  • 執(zhí)行 async1函數(shù),輸出 async1 start
  • 執(zhí)行 async2 函數(shù),輸出 async2,async2 后面的輸出 async1 end進(jìn)入微任務(wù),等待下一輪的事件循環(huán)
  • 遇到第二個,將其里面的回調(diào)函數(shù)放到本輪同步任務(wù)執(zhí)行完畢后執(zhí)行
  • 遇到 new Promise,執(zhí)行里面的立即執(zhí)行函數(shù),輸出 promise1、promise2
  • then里面的回調(diào)函數(shù)進(jìn)入微任務(wù)隊(duì)列
  • 遇到同步任務(wù),輸出 script end
  • 執(zhí)行下一輪回到函數(shù),先依次輸出 nextTick 的函數(shù),分別是 nextTick1、nextTick2
  • 然后執(zhí)行微任務(wù)隊(duì)列,依次輸出 async1 end、promise3
  • 執(zhí)行timer 隊(duì)列,依次輸出 setTimeout0
  • 接著執(zhí)行 check 隊(duì)列,依次輸出 setImmediate
  • 300ms后,timer 隊(duì)列存在任務(wù),執(zhí)行輸出 setTimeout2

執(zhí)行結(jié)果如下:

  1. script start 
  2. async1 start 
  3. async2 
  4. promise1 
  5. promise2 
  6. script end 
  7. nextTick1 
  8. nextTick2 
  9. async1 end 
  10. promise3 
  11. setTimeout0 
  12. setImmediate 
  13. setTimeout2 

最后有一道是關(guān)于setTimeout與setImmediate的輸出順序

  1. setTimeout(() => { 
  2.   console.log("setTimeout"); 
  3. }, 0); 
  4.  
  5. setImmediate(() => { 
  6.   console.log("setImmediate"); 
  7. }); 

輸出情況如下:

  1. 情況一: 
  2. setTimeout 
  3. setImmediate 
  4.  
  5. 情況二: 
  6. setImmediate 
  7. setTimeout 

分析下流程:

  • 外層同步代碼一次性全部執(zhí)行完,遇到異步API就塞到對應(yīng)的階段
  • 遇到setTimeout,雖然設(shè)置的是0毫秒觸發(fā),但實(shí)際上會被強(qiáng)制改成1ms,時間到了然后塞入times階段
  • 遇到setImmediate塞入check階段
  • 同步代碼執(zhí)行完畢,進(jìn)入Event Loop
  • 先進(jìn)入times階段,檢查當(dāng)前時間過去了1毫秒沒有,如果過了1毫秒,滿足setTimeout條件,執(zhí)行回調(diào),如果沒過1毫秒,跳過
  • 跳過空的階段,進(jìn)入check階段,執(zhí)行setImmediate回調(diào)
  • 這里的關(guān)鍵在于這1ms,如果同步代碼執(zhí)行時間較長,進(jìn)入Event Loop的時候1毫秒已經(jīng)過了,setTimeout先執(zhí)行,如果1毫秒還沒到,就先執(zhí)行了setImmediate

參考文獻(xiàn)

https://segmentfault.com/a/1190000012258592

https://juejin.cn/post/6844904100195205133

 

https://vue3js.cn/interview/

 

責(zé)任編輯:武曉燕 來源: JS每日一題
相關(guān)推薦

2021-06-30 07:19:36

React事件機(jī)制

2021-06-07 09:41:48

NodeBuffer 網(wǎng)絡(luò)協(xié)議

2021-06-08 08:33:23

NodeStream數(shù)據(jù)

2021-06-03 08:14:01

NodeProcessJavaScript

2024-01-05 08:49:15

Node.js異步編程

2021-06-04 07:55:30

Node Fs 操作

2021-05-31 10:35:34

TCPWebSocket協(xié)議

2021-07-12 08:35:24

組件應(yīng)用場景

2021-06-01 08:25:06

Node.jsJavaScript運(yùn)行

2021-07-07 08:36:45

React應(yīng)用場景

2021-09-13 09:23:52

TypeScript命名空間

2021-05-27 09:00:00

Node.js開發(fā)線程

2021-06-15 10:01:02

應(yīng)用系統(tǒng)軟件

2024-08-26 14:52:58

JavaScript循環(huán)機(jī)制

2021-07-13 07:52:03

ReactHooks組件

2021-10-29 09:40:21

設(shè)計(jì)模式軟件

2021-07-29 07:55:20

React Fiber架構(gòu)引擎

2017-08-16 10:36:10

JavaScriptNode.js事件驅(qū)動

2021-06-29 09:47:34

ReactSetState機(jī)制

2021-06-02 09:42:29

Node. js全局對象
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 青青草在线视频免费观看 | 91看国产 | 日韩一区二区三区在线视频 | 久久久91精品国产一区二区三区 | 亚洲精品久久久久久一区二区 | 中文字幕精品视频 | 日本福利视频 | 国产高清精品在线 | 欧美日韩大片 | 激情网五月天 | 久热免费在线 | 国产精品久久 | 69热视频在线观看 | 中文字幕在线国产 | 日韩中文字幕在线免费 | 狠狠综合网| 在线看一区二区三区 | 国产一区二区精品在线 | 99精品电影 | 九九久久国产 | 日韩成人影院 | 亚洲精品一区二区三区在线 | 国产精品免费视频一区 | 欧美日韩在线播放 | 亚洲日本免费 | 国产剧情一区 | 九九精品在线 | 中文字幕av第一页 | 国产精品一区久久久久 | 午夜天堂精品久久久久 | 精品国产免费一区二区三区演员表 | 97avcc | 国产丝袜人妖cd露出 | 亚洲综合在线一区 | 天天综合天天 | 亚洲精品一区久久久久久 | 欧美三级成人理伦 | 国产日韩欧美中文 | 9久久精品 | 色女人天堂 | 久久亚洲国产精品 |