」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > JavaScript 事件循環:深入探討

JavaScript 事件循環:深入探討

發佈於2024-08-06
瀏覽:269

JavaScript Event Loop: A Deep Dive

JavaScript 是一種單執行緒語言,一次執行一個任務。然而,由於事件循環,它可以輕鬆處理非同步操作。事件循環是一個基本概念,它為 JavaScript 的並發模型提供了動力,使其能夠在不阻塞主執行緒的情況下有效地管理多個操作。在本文中,我們將探討 JavaScript 事件循環的複雜性,了解它的工作原理以及為什麼它對於開發響應式 Web 應用程式至關重要。

什麼是 JavaScript 事件循環?

事件循環是 JavaScript 用來處理非同步操作的機制。它不斷檢查呼叫堆疊和任務佇列,確保任務以正確的順序執行。事件循環的主要目標是透過管理同步和非同步程式碼的執行來保持應用程式的回應能力。

事件循環的關鍵元件

1。呼叫堆疊:

呼叫堆疊是一種依後進先出 (LIFO) 順序追蹤函數呼叫的資料結構。當一個函數被呼叫時,它被加入到堆疊中。當函數執行完成時,它將從堆疊中刪除。

2. Web API:

Web API 由瀏覽器(或 Node.js 環境)提供,用於處理非同步操作,例如 setTimeout、HTTP 請求(XMLHttpRequest、Fetch API)和 DOM 事件。這些 API 在 JavaScript 引擎之外運作。

3.回呼隊列(任務隊列):

回呼佇列是保存非同步操作回呼的資料結構。當呼叫堆疊為空時執行這些回調。

4。事件循環:

事件循環持續監視呼叫堆疊和回調佇列。如果呼叫堆疊為空,它將從佇列中取出第一個回調並將其推入堆疊,允許其執行。

事件循環如何運作

要了解事件循環,讓我們來看一個範例:

console.log('Start');

setTimeout(() => {
  console.log('Timeout');
}, 0);

console.log('End');

逐步執行:

1。初始化:

console.log('Start') 函數被推入呼叫堆疊並執行,將 Start 列印到控制台。然後該函數將從堆疊中刪除。

2.非同步操作:

setTimeout 函數被調用,並帶有回調和 0 毫秒的延遲。 setTimeout 函數被壓入呼叫堆疊,然後在設定計時器後立即刪除。回調被傳遞到 Web API。

3.續:

console.log('End') 函數被壓入呼叫堆疊並執行,將 End 印到控制台。然後該函數將從堆疊中刪除。

4。回調執行:

呼叫堆疊為空後,事件循環檢查回呼佇列。來自 setTimeout 的回呼被移到回調佇列,然後推送到呼叫堆疊,將 Timeout 列印到控制台。

微任務和巨集任務

在 JavaScript 中,任務分為兩種:微任務和巨集任務。理解它們之間的區別對於編寫高效的非同步程式碼至關重要。

1。微任務:

微任務包括 Promise 和 MutationObserver 回調。它們具有更高的優先級,並且在巨集任務之前執行。在每個巨集任務之後,事件循環都會檢查微任務佇列並執行所有可用的微任務。

2.宏任務:

巨集任務包括setTimeout、setInterval和I/O操作。它們按照新增到回調佇列的順序執行。

Promise 範例

考慮以下帶有承諾的例子:

console.log('Start');

setTimeout(() => {
  console.log('Timeout');
}, 0);

Promise.resolve().then(() => {
  console.log('Promise');
});

console.log('End');

逐步執行:

1。初始化:

console.log('Start') 印出 Start.
setTimeout 調度一個延遲為 0ms 的巨集任務。
Promise.resolve().then() 調度一個微任務。
console.log('End') 印出 End.

2.微任務執行:

檢查微任務隊列,執行promise回調,列印Promise。

3.宏任務執行:

檢查巨集任務佇列,執行setTimeout回調,列印Timeout。

使用事件循環的最佳實踐

1。避免阻塞主線程:

在網路工作者中執行繁重的計算或使用非同步模式來保持主執行緒回應。

2.使用 Promises 和 Async/Await:

Promise 和 async/await 可以更輕鬆地處理非同步操作並提高程式碼可讀性。

3.了解任務優先:

了解微任務和巨集任務之間的差異,以編寫更可預測和更有效率的程式碼。

結論

JavaScript 事件循環是一種強大的機制,可以在單執行緒環境中進行非同步程式設計。透過了解事件循環的工作原理,您可以編寫更有效率、反應更靈敏的 Web 應用程式。請記得利用 Promise、async/await 和 Web Worker 來有效管理非同步任務,確保流暢、無縫的使用者體驗。

版本聲明 本文轉載於:https://dev.to/mdhassanpatwary/javascript-event-loop-a-deep-dive-2289?1如有侵犯,請洽[email protected]刪除
最新教學 更多>
  • 如何從PHP中的數組中提取隨機元素?
    如何從PHP中的數組中提取隨機元素?
    從陣列中的隨機選擇,可以輕鬆從數組中獲取隨機項目。考慮以下數組:; 從此數組中檢索一個隨機項目,利用array_rand( array_rand()函數從數組返回一個隨機鍵。通過將$項目數組索引使用此鍵,我們可以從數組中訪問一個隨機元素。這種方法為選擇隨機項目提供了一種直接且可靠的方法。
    程式設計 發佈於2025-03-31
  • Python讀取CSV文件UnicodeDecodeError終極解決方法
    Python讀取CSV文件UnicodeDecodeError終極解決方法
    在試圖使用已內置的CSV模塊讀取Python中時,CSV文件中的Unicode Decode Decode Decode Decode decode Error讀取,您可能會遇到錯誤的錯誤:無法解碼字節 在位置2-3中:截斷\ uxxxxxxxx逃脫當CSV文件包含特殊字符或Unicode的路徑逃...
    程式設計 發佈於2025-03-31
  • \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    \“(1)vs.(;;):編譯器優化是否消除了性能差異?\”
    答案: 在大多數現代編譯器中,while(1)和(1)和(;;)之間沒有性能差異。編譯器: perl: 1 輸入 - > 2 2 NextState(Main 2 -E:1)V-> 3 9 Leaveloop VK/2-> A 3 toterloop(next-> 8 last-> 9 ...
    程式設計 發佈於2025-03-31
  • 如何同步迭代並從PHP中的兩個等級陣列打印值?
    如何同步迭代並從PHP中的兩個等級陣列打印值?
    同步的迭代和打印值來自相同大小的兩個數組使用兩個數組相等大小的selectbox時,一個包含country代碼的數組,另一個包含鄉村代碼,另一個包含其相應名稱的數組,可能會因不當提供了exply for for for the uncore for the forsion for for ytry...
    程式設計 發佈於2025-03-31
  • PHP陣列鍵值異常:了解07和08的好奇情況
    PHP陣列鍵值異常:了解07和08的好奇情況
    PHP數組鍵值問題,使用07&08 在給定數月的數組中,鍵值07和08呈現令人困惑的行為時,就會出現一個不尋常的問題。運行print_r($月份)返回意外結果:鍵“ 07”丟失,而鍵“ 08”分配給了9月的值。 此問題源於PHP對領先零的解釋。當一個數字帶有0(例如07或08)的前綴時,PHP...
    程式設計 發佈於2025-03-31
  • 您可以使用CSS在Chrome和Firefox中染色控制台輸出嗎?
    您可以使用CSS在Chrome和Firefox中染色控制台輸出嗎?
    在javascript console 中顯示顏色是可以使用chrome的控制台顯示彩色文本,例如紅色的redors,for for for for錯誤消息? 回答是的,可以使用CSS將顏色添加到Chrome和Firefox中的控制台顯示的消息(版本31或更高版本)中。要實現這一目標,請使用以下...
    程式設計 發佈於2025-03-31
  • 如何將來自三個MySQL表的數據組合到新表中?
    如何將來自三個MySQL表的數據組合到新表中?
    mysql:從三個表和列的新表創建新表 答案:為了實現這一目標,您可以利用一個3-way Join。 選擇p。 *,d.content作為年齡 來自人為p的人 加入d.person_id = p.id上的d的詳細信息 加入T.Id = d.detail_id的分類法 其中t.taxonomy ...
    程式設計 發佈於2025-03-31
  • 如何使用node-mysql在單個查詢中執行多個SQL語句?
    如何使用node-mysql在單個查詢中執行多個SQL語句?
    Multi-Statement Query Support in Node-MySQLIn Node.js, the question arises when executing multiple SQL statements in a single query using the node-mys...
    程式設計 發佈於2025-03-31
  • 如何限制動態大小的父元素中元素的滾動範圍?
    如何限制動態大小的父元素中元素的滾動範圍?
    在交互式接口中實現垂直滾動元素的CSS高度限制問題:考慮一個佈局,其中我們具有與用戶垂直滾動一起移動的可滾動地圖div,同時與固定的固定sidebar保持一致。但是,地圖的滾動無限期擴展,超過了視口的高度,阻止用戶訪問頁面頁腳。 $("#map").css({ margin...
    程式設計 發佈於2025-03-31
  • 如何使用PHP將斑點(圖像)正確插入MySQL?
    如何使用PHP將斑點(圖像)正確插入MySQL?
    essue VALUES('$this->image_id','file_get_contents($tmp_image)')";This code builds a string in PHP, but the function call fil...
    程式設計 發佈於2025-03-31
  • Java是否允許多種返回類型:仔細研究通用方法?
    Java是否允許多種返回類型:仔細研究通用方法?
    在Java中的多個返回類型:一種誤解類型:在Java編程中揭示,在Java編程中,Peculiar方法簽名可能會出現,可能會出現,使開發人員陷入困境,使開發人員陷入困境。 getResult(string s); ,其中foo是自定義類。該方法聲明似乎擁有兩種返回類型:列表和E。但這確實是如此嗎...
    程式設計 發佈於2025-03-31
  • 如何在鼠標單擊時編程選擇DIV中的所有文本?
    如何在鼠標單擊時編程選擇DIV中的所有文本?
    在鼠標上選擇div文本單擊帶有文本內容,用戶如何使用單個鼠標單擊單擊div中的整個文本?這允許用戶輕鬆拖放所選的文本或直接複製它。 在單個鼠標上單擊的div元素中選擇文本,您可以使用以下Javascript函數: function selecttext(canduterid){ if(d...
    程式設計 發佈於2025-03-31
  • 為什麼使用固定定位時,為什麼具有100%網格板柱的網格超越身體?
    為什麼使用固定定位時,為什麼具有100%網格板柱的網格超越身體?
    網格超過身體,用100%grid-template-columns 為什麼在grid-template-colms中具有100%的顯示器,當位置設置為設置的位置時,grid-template-colly修復了? 問題: 考慮以下CSS和html: class =“ snippet-code”> ...
    程式設計 發佈於2025-03-31
  • 如何簡化PHP中的JSON解析以獲取多維陣列?
    如何簡化PHP中的JSON解析以獲取多維陣列?
    php 試圖在PHP中解析JSON數據的JSON可能具有挑戰性,尤其是在處理多維數組時。要簡化過程,建議將JSON作為數組而不是對象解析。 執行此操作,將JSON_DECODE函數與第二個參數設置為true:[&&&&& && &&&&& json = JSON = JSON_DECODE($ ...
    程式設計 發佈於2025-03-31
  • 如何正確使用與PDO參數的查詢一樣?
    如何正確使用與PDO參數的查詢一樣?
    在pdo 中使用類似QUERIES在PDO中的Queries時,您可能會遇到類似疑問中描述的問題:此查詢也可能不會返回結果,即使$ var1和$ var2包含有效的搜索詞。錯誤在於不正確包含%符號。 通過將變量包含在$ params數組中的%符號中,您確保將%字符正確替換到查詢中。沒有此修改,PD...
    程式設計 發佈於2025-03-31

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

Copyright© 2022 湘ICP备2022001581号-3