」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > Node.js 中的事件循環如何運作?

Node.js 中的事件循環如何運作?

發佈於2024-08-24
瀏覽:836

How event loop work in Node.js?

事件循環是 Node.js 中的一個核心概念,它使其能夠有效地處理非同步操作。以下是其運作方式的簡化說明:

1. 單線程性質

Node.js 在單執行緒上運行。這意味著它一次只能執行一段程式碼。然而,Node.js 被設計為可以同時處理許多操作,而不需要多個執行緒。

2. 非阻塞I/O

Node.js 使用非阻塞 I/O 操作。當 Node.js 執行讀取檔案、查詢資料庫或發出網路請求等任務時,它不會等待這些任務完成就繼續執行下一個任務。相反,它在處理這些任務時繼續執行其他程式碼。

3. 事件循環機制

事件循環負責管理程式碼的執行和處理非同步事件。它不斷檢查任務“隊列”並決定執行哪些任務。這是一步一步的細分:

  • 初始化:當 Node.js 應用程式啟動時,它會初始化並設定環境。
  • 執行階段:Node.js 同步執行任何初始程式碼。如果存在非同步任務(例如檔案讀取或 HTTP 請求),它們將被移交給系統的 API。
  • 事件循環階段:事件循環有幾個階段,它按特定順序處理每個階段中的任務:
    • 定時器階段:執行由setTimeout()和setInterval()安排的回呼。
    • IO Callbacks Phase:執行I/O操作的回調,例如檔案讀取或網路請求。
    • 空閒,準備階段:用於系統任務的內部階段。
    • Poll Phase:檢索新的 I/O 事件,執行它們的回呼。如果poll佇列為空,則會檢查setImmediate()佇列中是否有回呼。
    • 檢查階段:執行setImmediate()安排的回調。
    • 關閉回呼階段:處理關閉事件,例如由socket.on('close').
    • 發出的事件
  • 重新檢查並退出:如果事件循環沒有更多任務要處理,它將退出,讓程式終止。如果還有待處理的任務,它將繼續運作。

4. 回呼隊列

非同步任務完成後,將其回調推送到佇列。事件循環從佇列中選取這些回調並按順序執行它們。

5.微任務隊列(下一個Tick)

除了主佇列之外,還有一個微任務佇列(或下一個滴答佇列),其中使用 process.nextTick() 或 Promise 的 .then() 處理程序調度的回呼排隊。微任務優先於常規回調,這意味著它們在當前操作完成之後、事件循環進入下一階段之前執行。

例子

以下是一個簡單的例子來說明事件循環是如何運作的:

const fs = require('fs');

console.log('Start');

fs.readFile('file.txt', (err, data) => {
  if (err) throw err;
  console.log('File read complete');
});

console.log('End');

輸出:

Start
End
File read complete

解釋:

  1. console.log('開始');和 console.log('結束');同步執行。
  2. fs.readFile 啟動非同步檔案讀取操作,不等待繼續執行下一行程式碼。
  3. 一旦檔案讀取操作完成,其回呼(console.log('檔案讀取完成');)就會被推送到事件循環的回呼佇列中。
  4. 事件循環在同步程式碼執行完成後處理回呼。

儘管 Node.js 是單線程的,但事件循環允許 Node.js 透過將操作委託給系統並非同步處理其結果來有效地一次處理多個操作。

事件循環編排任務的執行,優先考慮微任務隊列,以確保在繼續執行主任務隊列中的任務之前快速解決承諾和相關操作(宏任務)。

這種動態使 JavaScript 能夠在單線程環境中處理複雜的異步行為。

版本聲明 本文轉載於:https://dev.to/syed_ammar/how-event-loop-work-in-nodejs-4lf4?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 我可以將加密從McRypt遷移到OpenSSL,並使用OpenSSL遷移MCRYPT加密數據?
    我可以將加密從McRypt遷移到OpenSSL,並使用OpenSSL遷移MCRYPT加密數據?
    將我的加密庫從mcrypt升級到openssl 問題:是否可以將我的加密庫從McRypt升級到OpenSSL?如果是這樣,如何? 答案:是的,可以將您的Encryption庫從McRypt升級到OpenSSL。 可以使用openssl。 附加說明: [openssl_decrypt()函數要求...
    程式設計 發佈於2025-04-26
  • 如何在GO編譯器中自定義編譯優化?
    如何在GO編譯器中自定義編譯優化?
    在GO編譯器中自定義編譯優化 GO中的默認編譯過程遵循特定的優化策略。 However, users may need to adjust these optimizations for specific requirements.Optimization Control in Go Compi...
    程式設計 發佈於2025-04-26
  • 在Java中如何為PNG文件添加坐標軸和標籤?
    在Java中如何為PNG文件添加坐標軸和標籤?
    如何用java 在現有png映像中添加軸和標籤的axes和labels如何註釋png文件可能具有挑戰性。與其嘗試可能導致錯誤和不一致的修改,不如建議在圖表創建過程中集成註釋。 使用JFReechArt import java.awt.color; 導入java.awt.eventqueue; 導...
    程式設計 發佈於2025-04-26
  • 如何使用Python理解有效地創建字典?
    如何使用Python理解有效地創建字典?
    在python中,詞典綜合提供了一種生成新詞典的簡潔方法。儘管它們與列表綜合相似,但存在一些顯著差異。 與問題所暗示的不同,您無法為鑰匙創建字典理解。您必須明確指定鍵和值。 For example:d = {n: n**2 for n in range(5)}This creates a dict...
    程式設計 發佈於2025-04-26
  • Python中何時用"try"而非"if"檢測變量值?
    Python中何時用"try"而非"if"檢測變量值?
    使用“ try“ vs.” if”來測試python 在python中的變量值,在某些情況下,您可能需要在處理之前檢查變量是否具有值。在使用“如果”或“ try”構建體之間決定。 “ if” constructs result = function() 如果結果: 對於結果: ...
    程式設計 發佈於2025-04-26
  • 如何實時捕獲和流媒體以進行聊天機器人命令執行?
    如何實時捕獲和流媒體以進行聊天機器人命令執行?
    在開發能夠執行命令的chatbots的領域中,實時從命令執行實時捕獲Stdout,一個常見的需求是能夠檢索和顯示標準輸出(stdout)在cath cath cant cant cant cant cant cant cant cant interfaces in Chate cant inter...
    程式設計 發佈於2025-04-26
  • 為什麼PHP的DateTime :: Modify('+1個月')會產生意外的結果?
    為什麼PHP的DateTime :: Modify('+1個月')會產生意外的結果?
    使用php dateTime修改月份:發現預期的行為在使用PHP的DateTime類時,添加或減去幾個月可能並不總是會產生預期的結果。正如文檔所警告的那樣,“當心”這些操作的“不像看起來那樣直觀。 考慮文檔中給出的示例:這是內部發生的事情: 現在在3月3日添加另一個月,因為2月在2001年只有2...
    程式設計 發佈於2025-04-26
  • 在Ubuntu/linux上安裝mysql-python時,如何修復\“ mysql_config \”錯誤?
    在Ubuntu/linux上安裝mysql-python時,如何修復\“ mysql_config \”錯誤?
    mysql-python安裝錯誤:“ mysql_config找不到”“ 由於缺少MySQL開發庫而出現此錯誤。解決此問題,建議在Ubuntu上使用該分發的存儲庫。使用以下命令安裝Python-MysqldB: sudo apt-get安裝python-mysqldb sudo pip in...
    程式設計 發佈於2025-04-26
  • 如何正確使用與PDO參數的查詢一樣?
    如何正確使用與PDO參數的查詢一樣?
    在pdo 中使用類似QUERIES在PDO中的Queries時,您可能會遇到類似疑問中描述的問題:此查詢也可能不會返回結果,即使$ var1和$ var2包含有效的搜索詞。錯誤在於不正確包含%符號。 通過將變量包含在$ params數組中的%符號中,您確保將%字符正確替換到查詢中。沒有此修改,PD...
    程式設計 發佈於2025-04-26
  • 解決MySQL錯誤1153:數據包超出'max_allowed_packet'限制
    解決MySQL錯誤1153:數據包超出'max_allowed_packet'限制
    mysql錯誤1153:故障排除比“ max_allowed_pa​​cket” bytes 更大的數據包,用於面對陰謀mysql錯誤1153,同時導入數據capase doft a Database dust?讓我們深入研究罪魁禍首並探索解決方案以糾正此問題。 理解錯誤此錯誤表明在導入過程中...
    程式設計 發佈於2025-04-26
  • 如何在其容器中為DIV創建平滑的左右CSS動畫?
    如何在其容器中為DIV創建平滑的左右CSS動畫?
    通用CSS動畫,用於左右運動 ,我們將探索創建一個通用的CSS動畫,以向左和右移動DIV,從而到達其容器的邊緣。該動畫可以應用於具有絕對定位的任何div,無論其未知長度如何。 問題:使用左直接導致瞬時消失 更加流暢的解決方案:混合轉換和左 [並實現平穩的,線性的運動,我們介紹了線性的轉換。...
    程式設計 發佈於2025-04-26
  • 如何在鼠標單擊時編程選擇DIV中的所有文本?
    如何在鼠標單擊時編程選擇DIV中的所有文本?
    在鼠標上選擇div文本單擊帶有文本內容,用戶如何使用單個鼠標單擊單擊div中的整個文本?這允許用戶輕鬆拖放所選的文本或直接複製它。 在單個鼠標上單擊的div元素中選擇文本,您可以使用以下Javascript函數: function selecttext(canduterid){ if(d...
    程式設計 發佈於2025-04-26
  • 如何使用PHP從XML文件中有效地檢索屬性值?
    如何使用PHP從XML文件中有效地檢索屬性值?
    從php $xml = simplexml_load_file($file); foreach ($xml->Var[0]->attributes() as $attributeName => $attributeValue) { echo $attributeName,...
    程式設計 發佈於2025-04-26
  • 如何簡化PHP中的JSON解析以獲取多維陣列?
    如何簡化PHP中的JSON解析以獲取多維陣列?
    php 試圖在PHP中解析JSON數據的JSON可能具有挑戰性,尤其是在處理多維數組時。要簡化過程,建議將JSON作為數組而不是對象解析。 執行此操作,將JSON_DECODE函數與第二個參數設置為true:[&&&&& && &&&&& json = JSON = JSON_DECODE($ ...
    程式設計 發佈於2025-04-26
  • 為什麼我在Silverlight Linq查詢中獲得“無法找到查詢模式的實現”錯誤?
    為什麼我在Silverlight Linq查詢中獲得“無法找到查詢模式的實現”錯誤?
    查詢模式實現缺失:解決“無法找到”錯誤在Silverlight應用程序中,嘗試使用LINQ建立LINQ連接以錯誤而實現的數據庫”,無法找到查詢模式的實現。”當省略LINQ名稱空間或查詢類型缺少IEnumerable 實現時,通常會發生此錯誤。 解決問題來驗證該類型的質量是至關重要的。在此特定實例...
    程式設計 發佈於2025-04-26

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3