【js基礎修煉之路】- 微任務,宏任務和Event-Loop

一段代碼讓你了解Event-Loop

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什么時候執行呢?


c97f7fee-b283-4774-84d1-5458ccfab1c7.png

上面這張圖片是代碼執行的具體過程,console.log(1)是同步代碼,直接執行,遇到定時器后,定時器是異步任務,定時器的時間到了會馬上把回調函數加入宏任務隊列里面,Promise是同步任務,直接執行,promise().then是一個微任務,所以把console.log(4)放到了微任務的隊列,接著里面是一個定時器,時間到了就把定時器放到了宏任務隊列里面,當主線程的代碼執行完畢,會檢查微任務隊列里面是否有代碼沒執行,有代碼的話就一并執行,如果沒有,宏任務隊列里面的代碼會依次進入主線程,直到宏任務為空。這樣一分析,代碼的執行順序就很清晰了,分別是1 3 4 2 5。


(1)所有同步任務都在主線程上執行,形成一個 執行棧 。
(2)主線程之外,還存在一個"宏任務隊列" 。只要異步任務有了運行結果(例如定時器的時間到了,或者ajax請求回來數據了等等),就在"宏任務隊列"之中放置一個事件(對應的回調函數)。
(3)一旦"執行棧"中的所有同步任務執行完畢,系統就會讀取"微任務隊列"里面的任務,微任務執行完,再看看"宏任務隊列"里面有哪些事件。那些對應的異步任務,于是結束等待狀態,進入執行棧,開始執行。
(4)主線程不斷重復上面的第三步。

說了那么多,Event-Loop到底是啥?


上面一直在說微任務,宏任務,當前執行棧,瀏覽器怎么能知道什么時候執行宏任務,什么時候執行微任務,其實有一個這樣的機制不斷檢查是否該執行微任務了,或者宏任務。(這是個非常簡易的描述了,實際上會復雜很多)而這樣的操作就被稱為Event Loop。

微任務和宏任務都有哪些

宏任務
* 瀏覽器 node
I/O ? ?
setTimeout ? ?
setInterval ? ?
setImmediate ? ?
requestAnimationFrame ? ?
微任務
* 瀏覽器 node
Promise.then catch finally ? ?
process.nextTick ? ?
MutationObserver ? ?
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容