欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript的宏任務和微任務有哪些以及怎樣執(zhí)行的詳解

 更新時間:2025年08月05日 08:25:57   作者:宋小土  
這篇文章主要介紹了JavaScript的宏任務和微任務有哪些以及怎樣執(zhí)行的相關資料,宏任務(MacroTask)與微任務(MicroTask)是JavaScript異步執(zhí)行機制中的核心概念,直接影響代碼的執(zhí)行順序和性能,需要的朋友可以參考下

前言

Javascript 的執(zhí)行順序,眾所周知是按照順序自上而下執(zhí)行。

Javascript任務分為同步任務和異步任務,異步任務又分為宏任務和微任務,其中異步任務屬于耗時的任務。

一、宏任務和微任務是什么?

首先,js 是單線程語言,通俗理解就是,只有一個主線程,那么在任務多的情況下,就會出現(xiàn)死鎖等問題

單線程的局限性

單線程的局限性在于阻塞,如果一個任務耗時很長(如同步的無限循環(huán)或大量計算),會阻塞后續(xù)所有任務,導致頁面“卡死”。

那么如何解決單線程的缺陷?

JavaScript 通過 事件循環(huán)(Event Loop)實現(xiàn)非阻塞行為,意思是主線程會不斷檢查調(diào)用棧和任務隊列,當調(diào)用棧為空時,從任務隊列中取出回調(diào)任務執(zhí)行。

在 JavaScript 的事件循環(huán)(Event Loop)機制中,先執(zhí)行同步任務,再執(zhí)行異步任務,而異步任務分成了宏任務和微任務,宏任務和微任務決定了異步代碼的執(zhí)行順序。它們的區(qū)別在于執(zhí)行優(yōu)先級和觸發(fā)時機。

1.1宏任務

宏任務代表較大的、獨立的異步任務,由瀏覽器或 Node.js 安排在不同的任務隊列中執(zhí)行。
每次事件循環(huán)(Event Loop)會執(zhí)行一個宏任務,然后檢查并執(zhí)行所有微任務。

1.2.微任務

微任務是比宏任務更小的任務,通常用于處理高優(yōu)先級的異步操作。

每當一個宏任務執(zhí)行完畢,JS 引擎會立即清空整個微任務隊列,然后再執(zhí)行下一個宏任務。

二、宏任務、微任務是怎么執(zhí)行的?

首先,是先執(zhí)行同步代碼,遇到異步宏任務則將異步宏任務放入宏任務隊列中,遇到異步微任務則將異步微任務放入微任務隊列中,當所有同步代碼執(zhí)行完畢后,再將異步微任務從隊列中調(diào)入主線程執(zhí)行,微任務執(zhí)行完畢后再將異步宏任務從隊列中調(diào)入主線程執(zhí)行,一直循環(huán)直至所有任務執(zhí)行完畢。

注意:

這里容易錯誤的認為:就是微任務先于宏任務執(zhí)行!

其實不是,要明確:

1、那就是事件循環(huán)是從第一個宏任務開始!即:script 中的代碼,script 標簽(或模塊)的全局代碼是一個宏任務!

2、瀏覽器加載并執(zhí)行script 中的代碼時,這些同步代碼(如 console.log、變量聲明、函數(shù)調(diào)用等)會被視為第一個宏任務。

3、同步代碼執(zhí)行完后,才會處理微任務和其他宏任務

4、在 script 宏任務執(zhí)行期間,遇到的 Promise.then、MutationObserver 等微任務會被收集到微任務隊列。

5、同步代碼執(zhí)行完畢后,立即清空微任務隊列,然后才會處理下一個宏任務(如 setTimeout)。

宏任務會先進入主線程 但是執(zhí)行的時候會先執(zhí)行該宏任務當中的同步任務 然后執(zhí)行該宏任務中的微任務

當前宏任務執(zhí)行完畢后、下一個宏任務開始前,JavaScript 會清空所有微任務隊列。導致看上去是微任務比宏任務先執(zhí)行!

要理解事件循環(huán)的關鍵在于區(qū)分“加入隊列”和“執(zhí)行”這兩個步驟,以及明白微任務隊列的優(yōu)先級高于宏任務隊列。 雖然宏任務可能先進入隊列,但微任務會在當前宏任務執(zhí)行完畢后、下一個宏任務執(zhí)行前被優(yōu)先執(zhí)行。

三、舉個栗子

我舉個栗子,讓你明白執(zhí)行順序的問題

首先要明確 ,script中的整體代碼是最先執(zhí)行的任務!

宏任務:像你的“主要待辦事項”

比如:

今天要寫作業(yè)(script主代碼)

1小時后取快遞(setTimeout)

明天去體檢(setInterval)

微任務:像“主要事項完成后立刻要做的小事”,

比如:

寫完作業(yè)后立刻收拾書包(Promise.then)

取完快遞后立刻拆包裝(MutationObserver)

console.log("開始寫作業(yè)"); // 宏任務1(大事)
setTimeout(() => {
  console.log("1小時后:取快遞"); // 宏任務2(下一件大事)
}, 0);
Promise.resolve().then(() => {
  console.log("寫完作業(yè)后:收拾書包"); // 微任務(小事)
});

那么執(zhí)行順序是:

先執(zhí)行第一個宏任務(script整體代碼),輸出 開始寫作業(yè) 和 作業(yè)寫完了。
立刻執(zhí)行這個宏任務產(chǎn)生的微任務(收拾書包)。
最后執(zhí)行下一個宏任務(取快遞)。

四、宏任務、微任務有哪些?

4.1宏任務

4.2 微任務

注意:

new Promise(…)是構造函數(shù),是同步代碼。

五、案例

<script>
console.log('開始'); // 宏任務1
//宏任務A
setTimeout(() => {
  console.log("宏任務A");
  Promise.resolve().then(() => console.log("微任務A"));
}, 0);

//宏任務B
setTimeout(() => {
  console.log('宏任務B');
}, 0);

Promise.resolve().then(() => {
  console.log('微任務');
});
</script>
//開始   微任務 宏任務A  微任務A    宏任務B

輸出過程:
代碼執(zhí)行的時候,先執(zhí)行全局代碼中的同步代碼 輸出:開始
然后執(zhí)行 全局代碼中的微任務 輸出 微任務
微任務執(zhí)行完畢后

主線程會檢查調(diào)用棧把宏任務A調(diào)入進行執(zhí)行
但是會先執(zhí)行宏任務A中的同步任務會先輸出, 輸出 宏任務A
然后輸出微任務A,等到宏任務A全部執(zhí)行完畢后

主線程會檢查調(diào)用棧調(diào)用棧會把 宏任務B調(diào)入進行執(zhí)行
但是宏任務B中沒有微任務 所以直接輸出 宏任務B

這里我解釋一下 為什么 宏任務A比微任務A先輸出 ,因為宏任務A是該宏任務中的同步任務 所以先執(zhí)行輸出

setTimeout(function(){
	console.log('1');
});
new Promise(function(resolve){		    
	console.log('2');
	resolve();
}).then(function(){		    
	console.log('3');
}).then(function(){
console.log('4')
}); 		
console.log('5');
// 2 5 3 4 1
console.log("Script start");

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

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

console.log("Script end"); 、

//Script start
//Script end
//Promise 1
//Promise 2
//setTimeout
setTimeout(()=>{
  new Promise(resolve =>{
  	resolve();
  }).then(()=>{
  	console.log('test');
  });

  console.log(4);
});

new Promise(resolve => {
  resolve();
  console.log(1)
}).then( () => {
  console.log(3);
  Promise.resolve().then(() => {
    console.log('before timeout');
  }).then(() => {
    Promise.resolve().then(() => {
      console.log('also before timeout')
    })
  })
})
console.log(2);
// 1  2  3  before timeout   also before timeout 4 test

總結 

到此這篇關于JavaScript的宏任務和微任務有哪些以及怎樣執(zhí)行的文章就介紹到這了,更多相關js宏任務和微任務內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論