javascript中的異步 macrotask 和 microtask 簡介
javascript中的異步 macrotask 和 microtask 簡介
什麽是macrotask?什麽是microtask?
在理解什麽是macrotask?什麽是microtask之前,我們先來看看javascript中的事件循環機制,先看如下面一段代碼:
console.log(1); setTimeout(function(){ console.log(2); }, 0); console.log(3);
很明顯 上面運行的結果是 1,3,2;
上面代碼 setTimeout的延時為0,可以理解為setTimeout為異步函數調用,這是因為javascript是單線程的,主線程擁有一個執行棧以及一個任務隊列
Macrotasks和Microtasks
Macrotasks和Microtasks 都屬於上述的異步任務中的一種,他們分別有如下API:
macrotasks: setTimeout, setInterval, setImmediate, I/O, UI rendering
microtasks: process.nextTick, Promise, MutationObserver
setTimeout的macrotask, 和 Promise的microtask 有哪些不同,先來看下代碼如下:
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
也就是說如果某個microtask任務被推入到執行中,那麽當主線程任務執行完成後,會循環調用該隊列任務中的下一個任務來執行,直到該任務隊列到最後一個任務為止。而事件循環每次只會入棧一個macrotask,主線程執行完成該任務後又會檢查microtasks隊列並完成裏面的所有任務後再執行macrotask的任務。
Microtask的應用:
為啥要用microtask? 根據 HTML Standrad, 在每個task運行完以後,UI都會重新渲染,那麽在microtask中就完成數據更新,因此當前task
結束就可以得到最新的UI了。反之:如果新建一個task來做數據更新的話,那麽渲染會執行兩次。知乎如下回答(https://www.zhihu.com/question/55364497/answer/144215284)
javascript中的異步 macrotask 和 microtask 簡介