javascript中的異步 macrotask 和 microtask 簡介

javascript中的異步 macrotask 和 microtask 簡介javascript

什麼是macrotask?什麼是microtask?
在理解什麼是macrotask?什麼是microtask以前,咱們先來看看javascript中的事件循環機制,先看以下面一段代碼:java

console.log(1);
setTimeout(function(){
  console.log(2);
}, 0);
console.log(3);

很明顯 上面運行的結果是 1,3,2;
上面代碼 setTimeout的延時爲0,能夠理解爲setTimeout爲異步函數調用,這是由於javascript是單線程的,主線程擁有一個執行棧以及一個任務隊列
,主線程會依次執行代碼,當遇到異步函數時候,會先將該函數入棧,全部主線程函數運行完畢後再將異步函數出棧,直到全部的異步函數執行完畢便可。promise

Macrotasks和Microtasks異步

Macrotasks和Microtasks 都屬於上述的異步任務中的一種,他們分別有以下API:
macrotasks: setTimeout, setInterval, setImmediate, I/O, UI rendering
microtasks: process.nextTick, Promise, MutationObserver函數

setTimeout的macrotask, 和 Promise的microtask 有哪些不一樣,先來看下代碼以下:spa

console.log(1);
setTimeout(function(){
  console.log(2);
}, 0);
Promise.resolve().then(function(){
  console.log(3);
}).then(function(){
  console.log(4);
});

上面的代碼輸出的是 1, 3, 4, 2;線程

如上代碼能夠看到,Promise的函數代碼的異步任務會優先於setTimeout的延時爲0的任務先執行。
緣由是任務隊列分爲 macrotasks 和 microtasks, 而promise中的then方法的函數會被推入到microtasks隊列中,而setTimeout函數會被推入到macrotasks
任務隊列中,在每一次事件循環中,macrotask只會提取一個執行,而microtask會一直提取,直到microsoft隊列爲空爲止。
也就是說若是某個microtask任務被推入到執行中,那麼當主線程任務執行完成後,會循環調用該隊列任務中的下一個任務來執行,直到該任務隊列到最後一個任務爲止。而事件循環每次只會入棧一個macrotask,主線程執行完成該任務後又會檢查microtasks隊列並完成裏面的全部任務後再執行macrotask的任務。code

Microtask的應用:
爲啥要用microtask? 根據 HTML Standrad, 在每一個task運行完之後,UI都會從新渲染,那麼在microtask中就完成數據更新,所以當前task
結束就能夠獲得最新的UI了。反之:若是新建一個task來作數據更新的話,那麼渲染會執行兩次。知乎以下回答(https://www.zhihu.com/question/55364497/answer/144215284)server

相關文章
相關標籤/搜索