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

面試官:說說對 Node.js 中的事件循環機制理解?

開發 前端
在瀏覽器事件循環中,我們了解到javascript在瀏覽器中的事件循環機制,其是根據HTML5定義的規范來實現

本文轉載自微信公眾號「JS每日一題」,作者灰灰。轉載本文請聯系JS每日一題公眾號。  

一、是什么

在瀏覽器事件循環中,我們了解到javascript在瀏覽器中的事件循環機制,其是根據HTML5定義的規范來實現

而在NodeJS中,事件循環是基于libuv實現,libuv是一個多平臺的專注于異步IO的庫,如下圖最右側所示:

上圖EVENT_QUEUE 給人看起來只有一個隊列,但EventLoop存在6個階段,每個階段都有對應的一個先進先出的回調隊列

二、流程

上節講到事件循環分成了六個階段,對應如下:

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

每個階段對應一個隊列,當事件循環進入某個階段時, 將會在該階段內執行回調,直到隊列耗盡或者回調的最大數量已執行, 那么將進入下一個處理階段

除了上述6個階段,還存在process.nextTick,其不屬于事件循環的任何一個階段,它屬于該階段與下階段之間的過渡, 即本階段執行結束, 進入下一個階段前, 所要執行的回調,類似插隊

流程圖如下所示:

在Node中,同樣存在宏任務和微任務,與瀏覽器中的事件循環相似

微任務對應有:

  • next tick queue:process.nextTick
  • other queue:Promise的then回調、queueMicrotask

宏任務對應有:

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

其執行順序為:

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

三、題目

通過上面的學習,下面開始看看題目

  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'

分析過程:

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

執行結果如下:

  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 

最后有一道是關于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 

分析下流程:

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

參考文獻

https://segmentfault.com/a/1190000012258592

https://juejin.cn/post/6844904100195205133

 

https://vue3js.cn/interview/

 

責任編輯:武曉燕 來源: JS每日一題
相關推薦

2021-06-30 07:19:36

React事件機制

2021-06-08 08:33:23

NodeStream數據

2021-06-07 09:41:48

NodeBuffer 網絡協議

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協議

2021-07-12 08:35:24

組件應用場景

2021-07-07 08:36:45

React應用場景

2021-06-01 08:25:06

Node.jsJavaScript運行

2021-09-13 09:23:52

TypeScript命名空間

2021-05-27 09:00:00

Node.js開發線程

2021-06-15 10:01:02

應用系統軟件

2024-08-26 14:52:58

JavaScript循環機制

2021-07-13 07:52:03

ReactHooks組件

2021-10-29 09:40:21

設計模式軟件

2017-08-16 10:36:10

JavaScriptNode.js事件驅動

2021-07-29 07:55:20

React Fiber架構引擎

2021-06-29 09:47:34

ReactSetState機制

2021-06-02 09:42:29

Node. js全局對象
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 三级国产三级在线 | 日韩av一二三区 | 欧美 日韩 国产 成人 | 久久久久久一区 | 2018天天干天天操 | 91精品国产综合久久久久蜜臀 | 在线中文字幕第一页 | 国产91视频播放 | 午夜影院普通用户体验区 | 国产精品一区二区久久 | 欧美www在线| 污视频在线免费观看 | 精品久久久久久 | 精品视频在线观看 | 久久成人精品视频 | 日韩精品在线播放 | 黄色一级特级片 | 欧美国产日韩精品 | 久久久久国产精品一区 | 欧美一级电影免费 | 日韩精彩视频 | 久久久久久久av | 亚洲夜射 | 精品一区二区三区在线观看 | 欧美日韩一区二区视频在线观看 | 国产精品久久久久久久久动漫 | 国产亚洲成av人片在线观看桃 | 一区二区在线不卡 | 国产一区二区精品在线 | 亚洲午夜精品一区二区三区 | 久色网| 久久久久久看片 | 国产精品久久久久久久久久久久久久 | 国产精品久久久久久久久久了 | 亚洲精品一区二区三区蜜桃久 | 天天射网站 | 91影院在线观看 | 国产成人精品一区二区三区四区 | 日韩久久久久久 | 精品视频久久久 | 91资源在线 |