深入理解宏任務和微任務的區別

一、宏任務和微任務的概念

宏任務和微任務是瀏覽器非同步執行任務時的兩種不同類型。當瀏覽器非同步執行一個任務時,會首先將任務添加到任務隊列中,然後在執行棧清空後,從任務隊列中取出隊列頭的任務執行。

其中,包括一類稱為宏任務(macro task)的任務,又稱為 task。

還有一類稱為微任務(micro task)的任務,又稱為 jobs。

它們之間的區別在於它們被添加到任務隊列中的時機以及執行的優先順序。

二、宏任務和微任務的執行時機

JavaScript 引擎會維護一個執行棧,也稱為調用棧(call stack)。執行棧採用後進先出(LIFO)的原則。

每當 JavaScript 引擎執行一個函數時,它會將該函數加入到執行棧的頂部。當該函數執行結束後,JavaScript 引擎會將它從棧中彈出。

當執行棧被清空時,JavaScript 引擎會從任務隊列中取出一個任務進行執行。

可見,宏任務和微任務的執行時機是不同的。

宏任務通常包括以下幾種:

– setTimeout 和 setInterval 回調函數

– I/O 操作的回調函數

– 事件的回調函數

– setImmediate 回調函數(Node.js 獨有)

而微任務通常包括以下幾種:

– Promise 回調函數

– process.nextTick 回調函數(Node.js 獨有)

三、宏任務和微任務的優先順序

在執行棧清空後,JavaScript 引擎會優先處理微任務隊列中的任務,直到隊列為空,然後再在宏任務隊列中取出一個任務執行。也就是說,微任務的優先順序高於宏任務。

舉個例子:

“`javascript
setTimeout(() => {
console.log(‘setTimeout’);
}, 0);

Promise.resolve().then(() => {
console.log(‘Promise’);
});
“`

上述代碼中,setTimeout() 和 Promise.resolve().then() 都是非同步操作,會被添加到宏任務隊列和微任務隊列中。當執行棧中的所有代碼執行完畢後,JavaScript 引擎會先執行微任務隊列中的 Promise,再執行宏任務隊列中的 setTimeout。因此,上述代碼執行結果為:

Promise

setTimeout

四、宏任務和微任務實例

實例1:

“`javascript
console.log(1);

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

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

console.log(4);
“`

執行過程:

1. 列印 1

2. 添加定時器回調函數到宏任務隊列中

3. 添加 Promise 回調函數到微任務隊列中

4. 列印 4

5. 執行微任務隊列中的 Promise

6. 執行宏任務隊列中的 setTimeout 回調函數

輸出結果為:

1, 4, 3, 2

實例2:

“`javascript
console.log(‘start’);

setTimeout(() => {
console.log(‘setTimeout’);
}, 0);

Promise.resolve().then(() => {
console.log(‘Promise 1’);
}).then(() => {
console.log(‘Promise 2’);
});

console.log(‘end’);
“`

執行過程:

1. 列印 start

2. 添加定時器回調函數到宏任務隊列中

3. 添加 Promise 回調函數到微任務隊列中

4. 列印 end

5. 執行微任務隊列中的 Promise 1

6. 執行 Promise 1 中的 then 回調函數,並將 Promise 2 添加到微任務隊列中

7. 執行微任務隊列中的 Promise 2

8. 執行宏任務隊列中的 setTimeout 回調函數

輸出結果為:

start, end, Promise 1, Promise 2, setTimeout

總結

在 JavaScript 中,宏任務和微任務的概念有助於我們理解非同步代碼的執行規則。在掌握了它們之間的區別和優先順序後,我們能更加準確地理解和編寫非同步代碼,從而提高代碼的效率。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/183057.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-24 16:26
下一篇 2024-11-24 16:26

相關推薦

  • Python中new和init的區別

    new和init都是Python中常用的魔法方法,它們分別負責對象的創建和初始化,本文將從多個角度詳細闡述它們的區別。 一、創建對象 new方法是用來創建一個對象的,它是一個類級別…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Sublime Test與Python的區別

    Sublime Text是一款流行的文本編輯器,而Python是一種廣泛使用的編程語言。雖然Sublime Text可以用於編寫Python代碼,但它們之間有很多不同之處。接下來從…

    編程 2025-04-29
  • Shell腳本與Python腳本的區別

    本文將從多個方面對Shell腳本與Python腳本的區別做詳細的闡述。 一、語法差異 Shell腳本和Python腳本的語法存在明顯差異。 Shell腳本是一種基於字元命令行的語言…

    編程 2025-04-29
  • Python中while語句和for語句的區別

    while語句和for語句是Python中兩種常見的循環語句,它們都可以用於重複執行一段代碼。然而,它們的語法和適用場景有所不同。本文將從多個方面詳細闡述Python中while語…

    編程 2025-04-29
  • Web程序和桌面程序的區別

    Web程序和桌面程序都是進行軟體開發的方式,但是它們之間存在很大的區別。本文將從多角度進行闡述。 一、運行方式 Web程序運行於互聯網上,用戶可以通過使用瀏覽器來訪問它。而桌面程序…

    編程 2025-04-29
  • Saturn 定時任務用法介紹

    本文將從以下幾個方面對Saturn定時任務進行詳細的闡述: 一、Saturn 定時任務簡介 Saturn是一個分散式任務調度系統,支持在線添加、修改定時任務,支持多種任務類型,如J…

    編程 2025-04-29
  • TensorFlow和Python的區別

    TensorFlow和Python是現如今最受歡迎的機器學習平台和編程語言。雖然兩者都處於機器學習領域的主流陣營,但它們有很多區別。本文將從多個方面對TensorFlow和Pyth…

    編程 2025-04-28
  • 麥語言與Python的區別

    麥語言和Python都是非常受歡迎的編程語言。它們各自有自己的優缺點和適合的應用場景。本文將從語言特性、語法、生態系統等多個方面,對麥語言和Python進行詳細比較和闡述。 一、語…

    編程 2025-04-28
  • MySQL bigint與long的區別

    本文將從數據類型定義、存儲空間、數據範圍、計算效率、應用場景五個方面詳細闡述MySQL bigint與long的區別。 一、數據類型定義 bigint在MySQL中是一種有符號的整…

    編程 2025-04-28

發表回復

登錄後才能評論