亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

前言

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

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

一、宏任務(wù)和微任務(wù)是什么?

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

單線程的局限性

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

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

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

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

1.1宏任務(wù)

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

1.2.微任務(wù)

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

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

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

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

注意:

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

其實不是,要明確:

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

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

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

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

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

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

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

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

三、舉個栗子

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

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

宏任務(wù):像你的“主要待辦事項”

比如:

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

1小時后取快遞(setTimeout)

明天去體檢(setInterval)

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

比如:

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

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

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

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

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

四、宏任務(wù)、微任務(wù)有哪些?

4.1宏任務(wù)

4.2 微任務(wù)

注意:

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

五、案例

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

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

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

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

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

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

這里我解釋一下 為什么 宏任務(wù)A比微任務(wù)A先輸出 ,因為宏任務(wù)A是該宏任務(wù)中的同步任務(wù) 所以先執(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

總結(jié) 

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

相關(guān)文章

最新評論