在javascript中,任務被分為兩種類型:宏任務和微任務。宏任務代表了一段需要在執行步驟間進行排隊的代碼,例如script標簽中的代碼、setTimeout和setInterval中的回調函數以及Ajax請求。微任務則代表了需要盡快執行的代碼,例如Promise中的回調函數、MutationObserver中的回調函數以及process.nextTick()。
在Promise中,then()函數中注冊的回調函數就是一個微任務。例如:
Promise.resolve('hello')
.then(value => {
console.log(${value} world
)
})
.then(() => {
console.log('next')
});
上述代碼中,第一個then()函數中的回調函數是一個微任務,它會在主任務(Promise.resolve())執行完畢后立即執行。第二個then()函數中的回調函數也是一個微任務,它會在第一個微任務執行完畢后立即執行。因此,在控制臺中的輸出為:
hello world next
除了Promise之外,MutationObserver中的回調函數也是一個微任務。例如:
const observer = new MutationObserver(() => { console.log('Mutated'); }); observer.observe(document.body, { childList: true }); document.body.innerHTML = '<div></div>';
上述代碼中,當document.body元素的子節點發生變化時,MutationObserver中的回調函數會被添加到微任務隊列中。在下一輪事件循環中,微任務隊列中的回調函數將被依次執行。因此,在控制臺中的輸出為:
Mutated
process.nextTick()方法也是創建微任務的一種方式。例如:
setTimeout(() => { console.log('setTimeout'); }); process.nextTick(() => { console.log('nextTick'); });
上述代碼中,process.nextTick()中的回調函數會在本輪事件循環中被優先執行,而setTimeout()中的回調函數則在下一輪事件循環中才會被執行。因此,在控制臺中的輸出為:
nextTick setTimeout
可以看到,在javascript中,微任務可以被用來代表一些需要盡快執行的代碼。在實際的編寫中,我們應該盡量減少宏任務的使用,盡可能使用微任務代替,以提高代碼執行效率。