js中的微任務和宏任務的理解

在JavaScript中,微任務(Microtask)和宏任務(Macrotask)是異步任務執行機制的重要組成部分,它們共同構成了JavaScript事件循環(Event Loop)的核心邏輯。理解這兩個概念對于編寫高性能、無阻塞的代碼至關重要。

1. 基本概念

宏任務(Macrotask)
  • 定義:由瀏覽器或Node.js環境提供的異步任務,通常是一些離散的、獨立的操作。
  • 常見宏任務
    • setTimeoutsetInterval
    • setImmediate(Node.js)
    • requestAnimationFrame(瀏覽器)
    • I/O操作(如文件讀取、網絡請求)
    • UI渲染(瀏覽器)
微任務(Microtask)
  • 定義:JavaScript引擎自身提供的異步任務,通常是需要在當前任務完成后立即執行的操作。
  • 常見微任務
    • Promise.then()Promise.catch()Promise.finally()
    • MutationObserver(瀏覽器)
    • process.nextTick(Node.js)
    • queueMicrotask(ES2020+)

2. 執行順序規則

JavaScript的事件循環執行機制遵循以下規則:

  1. 執行棧(Call Stack) 為空時,事件循環開始處理任務隊列。
  2. 宏任務隊列 每次只取一個任務執行,執行完畢后立即處理 微任務隊列
  3. 微任務隊列 會被清空(依次執行所有微任務),直到隊列為空。
  4. 微任務隊列清空后:
    • 瀏覽器可能進行 UI渲染(僅在瀏覽器環境)。
    • 事件循環回到步驟2,繼續處理下一個宏任務。

總結宏任務 → 清空微任務隊列 → UI渲染 → 下一個宏任務

3. 經典示例分析

console.log('1. 主線程開始');// 宏任務1
setTimeout(() => {console.log('2. setTimeout 回調執行');// 微任務1Promise.resolve().then(() => {console.log('3. setTimeout 內部 Promise 微任務執行');});
}, 0);// 微任務2
Promise.resolve().then(() => {console.log('4. 主線程 Promise 微任務執行');// 微任務3queueMicrotask(() => {console.log('5. queueMicrotask 微任務執行');});
});console.log('6. 主線程結束');

執行順序解析

  1. 主線程 執行:

    • 輸出 1. 主線程開始
    • setTimeout 被放入 宏任務隊列
    • Promise.then 被放入 微任務隊列(微任務2)。
    • 輸出 6. 主線程結束
  2. 微任務隊列 執行:

    • 執行微任務2,輸出 4. 主線程 Promise 微任務執行
    • queueMicrotask 被加入微任務隊列(微任務3)。
    • 繼續執行微任務3,輸出 5. queueMicrotask 微任務執行
  3. 宏任務隊列 執行:

    • 執行宏任務1(setTimeout 回調),輸出 2. setTimeout 回調執行
    • Promise.then 被加入微任務隊列(微任務1)。
    • 清空微任務隊列,執行微任務1,輸出 3. setTimeout 內部 Promise 微任務執行

最終輸出順序

1. 主線程開始
6. 主線程結束
4. 主線程 Promise 微任務執行
5. queueMicrotask 微任務執行
2. setTimeout 回調執行
3. setTimeout 內部 Promise 微任務執行

4. 實際應用場景

4.1 微任務的應用
  • Promise鏈式調用:確保回調按順序執行,不阻塞主線程。
    fetchData().then(processData).then(updateUI).catch(handleError);
    
  • DOM變更后立即操作:使用 MutationObserver 監聽DOM變化后執行回調。
4.2 宏任務的應用
  • 定時器:實現延遲執行或周期性任務。
    setTimeout(() => {// 延遲執行的代碼
    }, 1000);
    
  • 分批處理大量數據:避免長時間阻塞主線程。
    function processLargeData(data) {const batchSize = 1000;let index = 0;function processBatch() {const batch = data.slice(index, index + batchSize);// 處理當前批次數據index += batchSize;if (index < data.length) {setTimeout(processBatch, 0); // 使用宏任務拆分處理}}processBatch();
    }
    

5. 微任務 vs 宏任務的關鍵區別

特性微任務(Microtask)宏任務(Macrotask)
執行時機當前任務結束后立即執行(在渲染前)下一次事件循環開始時執行(可能在渲染后)
隊列清空規則一次性清空所有微任務每次只處理一個宏任務
觸發頻率高(可能在一次事件循環中多次觸發)低(每次事件循環只處理一個)
典型場景Promise回調、DOM變更監聽定時器、I/O操作、UI渲染

6. 注意事項

  1. 微任務阻塞渲染:如果微任務隊列過長,會導致UI長時間無法渲染,造成頁面卡頓。
  2. 合理選擇任務類型
    • 需要立即執行的異步操作(如Promise鏈)使用微任務。
    • 需要離散執行的操作(如定時器、大數據處理)使用宏任務。
  3. 瀏覽器兼容性queueMicrotask 是較新的API,舊瀏覽器可能需要使用 Promise.resolve().then() 替代。

通過理解微任務和宏任務的執行機制,你可以更精確地控制代碼的執行順序,避免性能問題,提升用戶體驗。

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

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

相關文章

Spring-AI系列-AI模型-Model

原文-知識庫&#xff0c;歡迎大家評論互動 AI Model API Portable ModelAPI across AI providers for Chat, Text to Image, Audio Transcription, Text to Speech, and Embedding models. Both synchronous and stream API options are supported. Dropping down to access mo…

MySQL查詢今天、昨天、上周、近30天、去年等的數據的方法

目錄 常用的MySQL查詢今天、昨天、上周、近30天、去年等數據的方法 0、Sql server中DateDiff()用法 1、MySQL的DATE_SUB()函數 定義和用法 語法 實例 2、MySQL的TO_DAYS(date) 3、MySQL的DATE() 函數 定義和用法 4、MySQL NOW() 函數 定義和用法 語法 實例 例子 …

Linux —— B / 基礎開發工具

一、軟件包管理器1.1什么是軟件包1.2 Linux軟件生態1.3 yum具體操作1.3.1 查看軟件包1.3.2 安裝軟件1.3.3 卸載軟件1.3.4 注意事項1.4 安裝源二、編輯器Vim2-1 Linux編輯器-vim使用2-2 vim的基本概念2-3 vim的基本操作2-4 vim正常模式命令集2-5 vim末行模式命令集2-6 vim操作總…

SQL,在join中,on和where的區別

0.結論 兩個表在&#xff0c;join時&#xff0c;首先做一個笛卡爾積&#xff0c;on后面的條件是對這個笛卡爾積做一個過濾形成一張臨時表&#xff0c;如果沒有where就直接返回結果&#xff0c;如果有where就對上一步的臨時表再進行過濾。 先on&#xff0c;再join&#xff0c;再…

SD-WAN在儲能網絡中的應用,傳統方案如何借力智能化升級?(附網絡架構圖)

一、儲能網絡的建設挑戰在儲能項目中&#xff0c;網絡系統通常需要實現以下目標&#xff1a;高可靠性&#xff1a;實時采集和傳輸儲能設備狀態數據&#xff0c;鏈路中斷可能導致系統故障。靈活擴展&#xff1a;分布式站點部署廣泛&#xff0c;傳統網絡擴展需重新鋪設線路&#…

Oracle11.2.0.4 RAC遷移升級Oracle19.3 RAC

問題描述 填寫問題的基礎信息。 系統名稱 Oracle11.2.0.4遷移升級Oracle19.3 IP地址 操作系統 Centos7.5 數據庫 Oracle11.2.0.4遷移升級Oracle19.3 癥狀表現 問題的癥狀表現如下 需要將單機的Oracle11.2.0.4環境升級到Oracle19.3.0RAC環境&#xff0c;采用遷移升級的…

SAP-ABAP:SAP的‘cl_http_utility=>escape_url‘對URL進行安全編碼方法詳解

SAP的’cl_http_utility>escape_url’對URL進行安全編碼方法詳解 核心作用&#xff1a;對 URL 進行安全編碼&#xff0c;將特殊字符轉換為 %XX 格式&#xff0c;確保符合 HTTP 傳輸規范。1. 功能與作用 ? URL 安全編碼 將非安全字符轉換為十六進制 ASCII 碼&#xff08;%XX…

基于HarmonyOS的智能燈光控制系統設計:從定時觸發到動作聯動全流程實戰

摘要 隨著智能家居的快速普及&#xff0c;人們對居住環境的智能化需求越來越高&#xff0c;其中智能燈光控制是最基礎、也是最常用的功能之一。從最初的遠程控制發展到如今能“感知環境、自動響應”的智能燈光系統&#xff0c;背后依賴的是強大的系統聯動能力。鴻蒙系統作為面向…

ROS1/Linux——linux虛擬機主ip地址:網絡信息不可用

ROS1/Linux——linux虛擬機主ip地址&#xff1a;網絡信息不可用 文章目錄ROS1/Linux——linux虛擬機主ip地址&#xff1a;網絡信息不可用參考億點鏈接問題描述最終解決方案參考億點鏈接 Unable to fetch some archives, maybe run apt-get update or try with –fix-missingli…

ssl相關命令生成證書

當前環境 OpenSSL 3.5.1 1 Jul 2025 (Library: OpenSSL 3.5.1 1 Jul 2025) GmSSL 3.1.2 Dev 本地gmssl命令 #生成證書公私鑰對 gmssl sm2keygen -pass 1234 -out sm2.key -pubout sm2pub.pem #使用certgen命令生成自簽名證書cert.crt gmssl certgen -C CN -ST Beijing -L Ha…

TensorFlow深度學習實戰——DCGAN詳解與實現

TensorFlow深度學習實戰——DCGAN詳解與實現0. 前言1. DCGAN 架構2. 構建 DCGAN 生成手寫數字圖像2.1 生成器與判別器架構2.2 構建 DCGAN相關鏈接0. 前言 深度卷積生成對抗網絡 (Deep Convolutional Generative Adversarial Network, DCGAN) 是一種基于生成對抗網絡 (Generati…

SpringBoot 使用MyBatisPlus

引入依賴<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId><version>4.3.0</version> </dependency>寫一個interface 繼承basemapMapper public in…

Git 中如何查看提交歷史?常用命令有哪些?

回答重點在 Git 中&#xff0c;我們可以使用 git log 命令來查看提交歷史。這個命令會列出所有的提交記錄&#xff0c;顯示每個提交的哈希值、作者信息、提交時間和提交信息。常用的 git log 命令及其選項有&#xff1a;1&#xff09; git log &#xff1a;顯示完整的提交歷史。…

Flink數據流高效寫入MySQL實戰

這段代碼展示了如何使用 Apache Flink 將數據流寫入 MySQL 數據庫&#xff0c;并使用了 JdbcSink 來實現自定義的 Sink 邏輯。以下是對代碼的詳細解析和說明&#xff1a;代碼結構包聲明&#xff1a;package sink定義了代碼所在的包。導入依賴&#xff1a;導入了必要的 Flink 和…

MATLAB下載安裝教程(附安裝包)2025最新版(MATLAB R2024b)

文章目錄前言一、MATLAB R2024b下載二、MATLAB下載安裝教程前言 MATLAB R2024b 的推出&#xff0c;進一步提升了其在工程實踐中的實用性和專業性。它不僅提供了更多針對特定工程領域的解決方案&#xff0c;還在性能和兼容性方面進行了顯著改進。 本教程將一步一步引導完成 MA…

Linux 基礎命令學習,立即上手Linux操作

Linux?基礎命令學習本文挑選最常用、最容易上手的 Linux 命令。每條都附帶一句話說明 真實示例&#xff0c;直接復制即可練習&#xff0c;零基礎也能跟得上。1? 先掌握 目錄導航&#xff1a;pwd?/?ls?/?cdpwd – 顯示當前所在目錄 pwd # 輸出示例 /home/yournamels??a…

Android構建流程與Transform任務

1. 完整構建流程概覽 1.1 主要構建階段 預構建階段 → 代碼生成階段 → 資源處理階段 → 編譯階段 → Transform階段 → 打包階段1.2 詳細任務執行順序 ┌─────────────────────────────────────────────────────────…

CKS認證 | Day6 監控、審計和運行時安全 sysdig、falco、審計日志

一、分析容器系統調用&#xff1a;Sysdig Sysdig&#xff1a;定位是系統監控、分析和排障的工具&#xff0c;在 linux 平臺上&#xff0c;已有很多這方面的工具 如tcpdump、htop、iftop、lsof、netstat&#xff0c;它們都能用來分析 linux 系統的運行情況&#xff0c;而且還有…

Redis:持久化配置深度解析與實踐指南

&#x1f9e0; 1、簡述 Redis 是一款基于內存的高性能鍵值數據庫&#xff0c;為了防止數據丟失&#xff0c;Redis 提供了兩種主要的持久化機制&#xff1a;RDB&#xff08;快照&#xff09;和 AOF&#xff08;追加日志&#xff09;。本文將從原理到配置&#xff0c;再到實際項目…

共創 Rust 十年輝煌時刻:RustChinaConf 2025 贊助與演講征集正式啟動

&#x1f680; 共創 Rust 十年輝煌時刻&#xff1a;RustChinaConf 2025 贊助與演講征集正式啟動2025年&#xff0c;是 Rust 編程語言誕生十周年的里程碑時刻。在這個具有歷史意義的節點&#xff0c;RustChinaConf 2025 攜手 RustGlobal 首次登陸中國&#xff0c;聯合 GOSIM HAN…