JavaScript事件循環機制

JavaScript 事件循環機制(Event Loop)詳解

JavaScript 是 單線程、非阻塞 語言,依賴 事件循環(Event Loop) 來實現異步編程。它的執行模型包括 調用棧(Call Stack)、任務隊列(Task Queue)和微任務隊列(Microtask Queue)


1. 事件循環(Event Loop)基本流程

事件循環的核心工作方式:

  1. 同步任務(Synchronous) 進入 調用棧 依次執行。
  2. 遇到 異步任務(如 setTimeout、Promise、I/O 操作),交給 Web API(如瀏覽器、Node.js 運行時)處理,并繼續執行同步代碼。
  3. 同步代碼執行完畢,調用棧清空,事件循環檢查 微任務隊列(Microtask Queue),依次執行所有微任務。
  4. 微任務執行完畢,進入 宏任務隊列(Macro Task Queue),取出第一個任務執行。
  5. 重復以上步驟。

2. 任務類型:同步任務 vs 異步任務

JavaScript 任務分為:

(1) 同步任務(Synchronous)

  • 直接執行,放入 調用棧(Call Stack)
  • 例子:
    console.log('同步任務1'); // 立即執行
    

(2) 異步任務(Asynchronous)

  • 由 Web API 處理,待合適時機進入任務隊列:
    • 宏任務(Macro Task)
    • 微任務(Micro Task)

3. 宏任務(Macro Task) vs 微任務(Micro Task)

任務類型常見API進入隊列
宏任務(Macro Task)setTimeoutsetIntervalsetImmediate(Node.js)、I/OUI渲染任務隊列(Task Queue)
微任務(Micro Task)Promise.then()queueMicrotask()MutationObserverprocess.nextTick()(Node.js)微任務隊列(Microtask Queue)

4. 事件循環執行流程

console.log('同步任務1');setTimeout(() => {console.log('宏任務1');
}, 0);Promise.resolve().then(() => {console.log('微任務1');
});console.log('同步任務2');

執行順序解析

  1. console.log('同步任務1') 執行(同步任務)
  2. setTimeout() 放入 宏任務隊列,等待執行
  3. Promise.then() 放入 微任務隊列
  4. console.log('同步任務2') 執行(同步任務)
  5. 調用棧清空,檢查 微任務隊列,執行 console.log('微任務1')
  6. 微任務清空后,執行 宏任務隊列,輸出 console.log('宏任務1')
最終輸出順序
同步任務1
同步任務2
微任務1
宏任務1

5. setTimeout(fn, 0) 為什么不立即執行?

  • setTimeout(fn, 0) 也會進入 宏任務隊列,需要等當前同步任務執行完畢,并在 微任務全部執行完畢后,才能執行。
  • 示例
    setTimeout(() => console.log('宏任務'), 0);
    Promise.resolve().then(() => console.log('微任務'));
    console.log('同步任務');
    
    執行順序
    同步任務
    微任務
    宏任務
    

6. PromisesetTimeout 誰先執行?

  • Promise.then() 是微任務,會先執行
  • setTimeout() 是宏任務,等微任務執行完才執行

示例

setTimeout(() => console.log('setTimeout'), 0);
Promise.resolve().then(() => console.log('Promise'));

執行順序

Promise
setTimeout

7. 事件循環完整示例

console.log('start');setTimeout(() => {console.log('setTimeout');
}, 0);Promise.resolve().then(() => {console.log('Promise1');
}).then(() => {console.log('Promise2');
});console.log('end');

執行順序

  1. console.log('start')(同步任務)
  2. setTimeout() 進入 宏任務隊列
  3. Promise.then() 進入 微任務隊列
  4. console.log('end')(同步任務)
  5. 同步任務結束,執行微任務
    • Promise1
    • Promise2
  6. 微任務執行完畢,執行宏任務
    • setTimeout

最終輸出:

start
end
Promise1
Promise2
setTimeout

8. async/await 也是微任務

示例

async function asyncFunc() {console.log('A');await Promise.resolve();console.log('B');
}console.log('C');
asyncFunc();
console.log('D');

執行順序

C
A
D
B

解釋

  1. console.log('C')(同步任務)
  2. 調用 asyncFunc(),輸出 A
  3. await Promise.resolve()console.log('B') 進入 微任務隊列
  4. console.log('D')(同步任務)
  5. 執行微任務
    • console.log('B')

9. setTimeout()setImmediate()(Node.js)

Node.js 中:

  • setTimeout(fn, 0) 進入 定時器隊列
  • setImmediate(fn) 進入 Check 隊列
  • setImmediate() 通常比 setTimeout(0) 先執行

示例

setTimeout(() => console.log('setTimeout'), 0);
setImmediate(() => console.log('setImmediate'));

輸出順序(Node.js)

setImmediate
setTimeout

10. 關鍵點總結

概念說明
同步任務立即執行,進入 調用棧
異步任務由 Web API 處理,稍后執行
宏任務(Macro Task)setTimeoutsetIntervalsetImmediateI/O
微任務(Micro Task)Promise.then()queueMicrotask()MutationObserver
事件循環(Event Loop)先執行同步任務 → 再執行微任務 → 再執行宏任務

11. 最佳實踐

? 避免阻塞主線程

  • 使用 setTimeout(fn, 0)requestIdleCallback(fn) 處理密集計算

? 優先使用微任務優化異步流程

  • Promise.then()setTimeout() 先執行

? 了解 async/await 也是微任務

  • await 后的代碼會在微任務隊列中執行

總結

  1. JavaScript 是單線程,使用事件循環管理異步任務
  2. 任務分為
    • 同步任務(調用棧直接執行)
    • 異步任務(進入宏任務/微任務隊列)
  3. 執行順序
    • 先執行同步任務
    • 再執行所有微任務
    • 最后執行宏任務
  4. Promise.then()setTimeout() 先執行
  5. async/await 本質上是 Promise,屬于微任務

這些概念對于理解 JavaScript 的異步執行至關重要!🚀

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/72041.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/72041.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/72041.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

大模型架構記錄4-文檔切分 (chunks構建)

chunks: 塊 trunks : 樹干 “RAG”通常指 檢索增強生成(Retrieval-Augmented Generation) 主要框架:用戶提query,找到和它相關的,先把問題轉換為向量,和向量數據庫的數據做比較,檢…

物聯網IoT系列之MQTT協議基礎知識

文章目錄 物聯網IoT系列之MQTT協議基礎知識物聯網IoT是什么?什么是MQTT?為什么說MQTT是適用于物聯網的協議?MQTT工作原理核心組件核心機制 MQTT工作流程1. 建立連接2. 發布和訂閱3. 消息確認4. 斷開連接 MQTT工作流程圖MQTT在物聯網中的應用 …

第27周JavaSpringboot電商進階開發 1.企業級用戶驗證

課程筆記:注冊郵箱驗證 一、概述 從本小節開始,將學習如何進行注冊郵箱驗證。主要任務是給項目配置一個公共郵箱(可自己注冊或由公司提供),用于向用戶發送驗證碼,幫助用戶完成注冊流程。課程中以QQ郵箱為…

數據庫---sqlite3

數據庫: 數據庫文件與普通文件區別: 1.普通文件對數據管理(增刪改查)效率低 2.數據庫對數據管理效率高,使用方便 常用數據庫: 1.關系型數據庫: 將復雜的數據結構簡化為二維表格形式 大型:Oracle、DB2 中型:MySql、SQLServer …

音視頻軟件工程師面試題

一、基礎知識 編解碼相關 H.264 和 H.265(HEVC)的主要區別是什么?視頻編解碼的基本流程是什么?關鍵技術有哪些?音頻編解碼(如 AAC、MP3、Opus)的區別和應用場景?什么是 B 幀、P 幀、I 幀?它們的作用是什么? 流媒體協議RTMP、HTTP-FLV、HLS、WebRTC 的區別和應用場景…

【系統架構設計師】測試方法

目錄 1. 說明2. 靜態測試3. 動態測試4. 黑盒測試5. 白盒測試6. 灰盒測試7. 自動化測試8.例題8.1 例題1 1. 說明 1.軟件測試方法的分類有很多種,以測試過程中程序執行狀態為依據可分為靜態測試(Static Testing,ST)和動態測試&…

tomcat配置應用----server.xml文件具體配置

1.tomcat項目目錄 默認項目目錄:tomcat安裝目錄/webapps目錄 如上圖所示,在tomcat的項目目錄下有很多子文件夾,這些子文件夾中都有一個項目首頁。 如上圖所示,將來我們去使用IP加端口號的方式去訪問tomcat的時候,默認是…

Spring Boot 調用DeepSeek API的詳細教程

目錄 前置準備步驟1:創建Spring Boot項目步驟2:配置API參數步驟3:創建請求/響應DTO步驟4:實現API客戶端步驟5:創建控制器步驟6:異常處理步驟7:測試驗證單元測試示例Postman測試請求 常見問題排查…

多維數據聚合方案:SQL GROUPING SETS深度解析

一、什么是GROUPING SETS? GROUPING SETS是SQL標準中的多維聚合運算符,允許在單個查詢中實現多維度組合的分組統計。相較于傳統UNION ALL方案,性能可提升3-10倍(TPC-DS基準測試)。 二、核心語法解析 SELECT column1,…

Excel中國式排名,3種方法!

大家好,我是小魚。 什么是中國式排名呢? 舉個例子比如說公司一共有10名員工進行成績考核,如果9個人考核成績都是90分,你是89分,按照國際慣用的排名法則:9 個人考核成績并列第一,你第10名&…

哪些業務場景更適合用MongoDB?何時比MySQL/PostgreSQL好用?

哪些業務場景更適合用MongoDB?何時比MySQL/PostgreSQL好用? 就像淘寶的個性化推薦需要靈活調整商品標簽,MongoDB這種"變形金剛"式的數據庫,在處理以下三類中國特色業務場景時更具優勢: 一、動態數據就像&q…

深度解讀:OpenAI發布GPT-5的技術突破與商業影響

引言 2025年2月,OpenAI正式發布GPT-5,這一被譽為“AI新紀元開篇之作”的模型,不僅實現了技術架構的顛覆性創新,更以免費開放策略引發行業地震。本文將從技術突破、商業影響、行業競爭格局及未來挑戰四個維度,全面解析…

網絡防火墻是什么有什么用_網絡防火墻:守護信息安全的重要屏障

網絡防火墻的基本概念 網絡防火墻是網絡安全領域的重要組成部分,它充當著內部網絡和外部網絡之間的安全防護層。防火墻能夠監控和控制進出網絡的數據流,只允許符合安全策略的信息通過,從而有效阻止潛在威脅的入侵。簡而言之,網絡…

C# WPF 串口通信

C# WPF 串口通信 安裝依賴庫 安裝依賴庫 System.IO.Ports using System.Diagnostics; using System.IO.Ports; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windo…

【玩轉23種Java設計模式】結構型模式篇:組合模式

軟件設計模式(Design pattern),又稱設計模式,是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性、程序的重用性。 匯總目錄鏈接&…

如何選取合適的 NewRatio 值來優化 JVM 的垃圾回收策略

目錄 一、垃圾回收模型簡介 (一)新生代(Young Generation) (二)老年代(Old Generation) (三)NewRatio 的作用與影響 (四)圖解&am…

Element Plus中的樹組件的具體用法(持續更新!)

const defaultProps {//子樹為節點對象的childrenchildren: children,//節點標簽為節點對象的name屬性label: name, } 屬性 以下是樹組件中的常用屬性以及作用: data:展示的數據(數據源) show-checkbox:節點是否可…

第十一屆藍橋杯單片機國賽

什么?4T模擬賽和省賽做起來輕輕松松?不妨來挑戰一下第十一屆國賽,這一屆的國賽居然沒考超聲波、串口通信!只要你正確地理解了題目的意思,規避出題人挖的坑,拿個國一輕輕松松。 附件:第十一屆藍橋…

大彩串口屏開發 —— MODBUS通信

目 錄 Modbus通信方式 1 使用變量與協議設置方式 2 使用LUA腳本方式 3 兩者結合 Modbus通信 大彩串口屏可以采用三種方式實現與其它設備進行modbus通信和邏輯處理。 方式 1 使用變量與協議設置 步驟1 在協議設置里進行設置,包括開啟modbus協議,屏做為主…