Microtask與Macrotask,異步執(zhí)行順序的差異
要明白這個問題需要去了解js的事件循環(huán)模型。了解過程中會明白js的執(zhí)行棧,作用域鏈,變量提升,js的單線程原因等許多問題。
關鍵詞:marcotask microtask queue 執(zhí)行上下文context 堆heap 棧stack 作用域
寫的很簡單,主要是思路,細節(jié)google就可以。
參考
引入
一個代碼執(zhí)行順序的例子:
console.log('script start');
setTimeout(function() {
console.log('setTimeout');
}, 0);
Promise.resolve().then(function() {
console.log('promise1');
}).then(function() {
console.log('promise2');
});
console.log('script end');
//script start
//script end
//promise1
//promise2
//undefined
//setTimeout
這里順序的判斷就涉及到了宏任務,微任務。
event loop
JS是單線程的語言,同步執(zhí)行代碼會造成阻塞,異步解決了這一問題。但是異步是如何實現(xiàn)的?
事件循環(huán)模型,event loop實現(xiàn)異步。
而在瀏覽器環(huán)境與NodeJs環(huán)境又有差異,NodeJs里的event loop更復雜一些,這里主要說明瀏覽器環(huán)境中的event loop,但是具體到不同瀏覽器上代碼的執(zhí)行順序也有差異。
- 總體上來講,setTimeout,setTimeInterval粒度更大,屬于宏任務,promise.then中的回調(diào)粒度小,是微任務。
- setTimeout,在0ms后將callback加入到宏任務的queue中,而promise的回調(diào)放在微任務的queue中
- 當前JS線程中的任務執(zhí)行完成后(正常代碼都會放入執(zhí)行棧中,執(zhí)行棧中空閑后),queue中的函數(shù)會按隊列執(zhí)行。先去微任務的queue,再去執(zhí)行宏任務隊列中的callback。