先看一個 實例
案例
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
setTimeout(function() {
console.log('setTimeout in microtask');
}, 0);
}).then(function() {
console.log('promise2');
});
console.log('script end');
輸出
script start
script end
promise1
promise2
setTimeout
setTimeout in microtask
Macrotask 和 Microtask
Macrotask 和 Microtask 都是屬於異步任務中的一種
- Macrotasks : setTimeout, setInterval, setImmediate, I/O, UI rendering
- Microtask : process.nextTick, Promises, Object.observe, MutationObserver
Mutation Observer(變動觀察器)是監視DOM變動的接口。當DOM對象樹發生任何變動時,Mutation Observer會得到通知。
Object.observe (廢棄):https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/observe
在每一次事件循環中,macrotask 只會提取一個執行,而 microtask 會一直提取,直到 microtasks 隊列清空。而事件循環每次只會入棧一個 macrotask ,主線程執行完該任務后又會先檢查 microtasks 隊列並完成里面的所有任務后再執行 macrotask
用處
可以看出 Macrotask 的優先級低於 Microtask ,那么 UI rendering 之前我們可以做很多數據上的處理,比如 Vue 使用 MutationObserver 可以處理完所有數據處理后再統一做 UI render
參考:
https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/