国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > JS > 正文

Node.js Event Loop各階段講解

2024-05-06 16:48:51
字體:
來源:轉載
供稿:網友

Event Loop階段描述圖

Node.js,Event,Loop

timers

timer階段處理setTimeout于setInterval回調,開始處理的時機與poll階段有關聯。

pending callbacks

該階段執行某些系統操作的回調,比如TCP套接字在連接時收到ECONNREFUSED。

網上有一些將該階段稱為I/O callbacks的文章都是過時錯誤的,具體可以移步Node.js官方庫下面的這個issue: #1118。

idle, prepare

內部使用,忽略。

poll

poll是一個核心階段,等新I/O事件的觸發,以及執行I/O相關回調。Node.js中出現異步的絕大部分情況都是I/O操作,它們的回調基本都在這個階段被執行。

poll階段主要做兩件事:

  • 計算需要為新的的I/O事件等待多久

當進入poll階段,如果隊列為空且不存在setImmediate與就緒的timer,Node.js會在這里block一定的時間等待新的I/O事件到來,然后立即執行其回調。這種情況具體block等待多久是不具體的,但如果在block一定時間后仍沒有新到達的I/O事件,可以肯定循環依舊會進入check階段或者回到timer階段。

  • 處理該階段隊列中的事件

當進入poll階段,如果隊列不為空且沒有就緒的timer,Node.js會在這里執行隊列中的callback直到隊列為空或者執行的callback數達到系統設定的某個值。隨后Node.js檢查是否存在預設的setImmediate,存在話就進入check階段,否則開始檢查timer就緒情況選擇回到timer階段或者進入check階段。

對于poll階段,通過閱讀官方的文檔有些細節也沒弄清楚,用偽代碼表示出來:

enter pool phase:if (has timer scheduled) {  // 官方沒有提到這種情況會做什么}else {  if (isEmpty(queue)) {    if (has(setImmediate)) {      // 進入check階段    }    else if (!isEmpty(timer)) {      // 回到timer階段    }    else {      // 等待新的I/O事件      // 新的I/O事件觸發回調立即執行,執行完成之后的邏輯不清楚    }    // 目前看來只有存在setImmediate時才會進入check階段,這肯定不合理  }  if (!isEmpty(queue)) {    let result = execute(queue);    if (result === 'queue is empty') {      // 官方沒講后續邏輯      // 猜測是回到隊列為空的處理邏輯中    }    if (result === 'reached hard limit') {      // 官方沒有解釋這里的后續邏輯      // 也許與queue is empty一樣對待    }  }}

疑惑重點是從poll階段出來的時機以及去向不是非常明確,但以我目前的水平和精力只能到此為止。

check

當poll階段執行完成會進入到check階段執行,該階段的執行內容是所有setImmediate回調。

close callbacks

socket的異常關閉,'close'事件的回調會在該階段執行。

process.nextTick

process.nextTick經常被用來做異步調用,但它并不屬于事件循環的內容,process.nextTick中的回調被放在nextTickQueue中等待“當前操作”完成后被立即處理,與事件循環中的階段沒有聯系,當前操作的原文定義是:“An operation is defined as a transition from the underlying C/C++ handler, and handling the JavaScript that needs to be executed.”,指的是在一段Javascript代碼執行完切換到C/C++層時會處理nextTickQueue。

文章提到了一個特例是Deduplication,這是Node.js內部一個優化特性,當在timer和check階段,同時有多個需要執行的回調時,切換只會發生一次,所以nextTick回調執行在這種情況下看似有所延后。

代碼示例:

setImmediate(() => {  console.log('1');  process.nextTick(() => console.log('2'));});setImmediate(() => {  console.log('3');  process.nextTick(() => console.log('4'));});

存在兩個setImmediate,進入check階段后需要在執行所有setImmediate的回調代碼后才會產生切換,從而執行nextTick回調,因此上面代碼的運行結果是:“1 3 2 4”,除上述場景外,nextTick都會先于setImmediate執行。

總結

因為Node.js的Event Loop我看了有那么2、3回,但經常忘,所以這次記錄下來,做個備忘。由于太多知識容易忘記,又發現寫文章的一個優點:“幫助記憶便于復習”。

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 洪江市| 尤溪县| 丹棱县| 错那县| 盐源县| 阿拉善右旗| 黄梅县| 台安县| 苍梧县| 稷山县| 邵东县| 屏东县| 奉化市| 日照市| 南阳市| 潢川县| 小金县| 松潘县| 宿迁市| 德清县| 西丰县| 谢通门县| 元阳县| 宣恩县| 高平市| 香格里拉县| 石棉县| 大丰市| 富宁县| 兴山县| 苍梧县| 云浮市| 南川市| 城口县| 成都市| 三亚市| 北辰区| 海南省| 运城市| 罗江县| 岚皋县|