console.log(1);
setTimeout(() => {
console.log(2);
}, 0);
new Promise((resolve, reject) => {
console.log(3);
resolve();
}).then(data => {
console.log(4);
setTimeout(() => {
console.log(5);
}, 0);
});
複製代碼
講解以前先看一段代碼,能夠先預測一下代碼的執行結果,首先打印了1,而後是一個定時器,由於js是單線程,因此代碼不會等到定時器執行完在繼續代碼,定時器會放到異步隊列裏面,等到合適的時機再執行。再下面是一個promise,那麼promise何時執行呢? node
(1)全部同步任務都在主線程上執行,造成一個 執行棧 。 (2)主線程以外,還存在一個"宏任務隊列" 。只要異步任務有了運行結果(例如定時器的時間到了,或者ajax請求回來數據了等等),就在"宏任務隊列"之中放置一個事件(對應的回調函數)。 (3)一旦"執行棧"中的全部同步任務執行完畢,系統就會讀取"微任務隊列"裏面的任務,微任務執行完,再看看"宏任務隊列"裏面有哪些事件。那些對應的異步任務,因而結束等待狀態,進入執行棧,開始執行。 (4)主線程不斷重複上面的第三步。ajax
上面一直在說微任務,宏任務,當前執行棧,瀏覽器怎麼能知道何時執行宏任務,何時執行微任務,其實有一個這樣的機制不斷檢查是否該執行微任務了,或者宏任務。(這是個很是簡易的描述了,實際上會複雜不少)而這樣的操做就被稱爲Event Loop。promise
#####宏任務瀏覽器
* | 瀏覽器 | node |
---|---|---|
I/O | ✅ | ✅ |
setTimeout | ✅ | ✅ |
setInterval | ✅ | ✅ |
setImmediate | ❌ | ✅ |
requestAnimationFrame | ✅ | ❌ |
#####微任務異步
* | 瀏覽器 | node |
---|---|---|
Promise.then catch finally | ✅ | ✅ |
process.nextTick | ❌ | ✅ |
MutationObserver | ✅ | ❌ |