宏任務和微任務:setTimeout和Promise執行順序


先以一道面試題做引子:

寫出這段程序的輸出內容:

        setTimeout(function(){
            console.log(1);
        },0);
        new Promise(function(a,b){
            console.log(2);
            for(var i=0;i<10;i++){
                i==9&&a();
            }
            console.log(3)
        }).then(function(){
            console.log(4)
        });
        console.log(5);

如果你看了這道題不知道怎么下手,或者發現結果和自己的答案大相徑庭,請繼續往下看

1. javascript事件循環
首先,你要知道javascript是單線程語言。js任務需要排隊順序執行,如果一個任務耗時過長,后邊一個任務也的等着,但是,假如我們需要瀏覽新聞,但新聞包含的超清圖片加載很慢,總不能網頁一直卡着直到圖片完全出來,所以將任務設計成了兩類:

同步任務
異步任務
當我們打開網站時,網頁的渲染過程就是一大堆同步任務,像頁面骨架和頁面元素的渲染,而加載圖片、音樂之類的任務就是異步任務,看一下下邊導圖:

 

如圖:

同步和異步任務分別進入不同的執行“場所”,同步進入主線程,異步進入Event Table並注冊函數。當指定的事情完成時,Event Table會將這個函數移入Event Queue。主線程內的任務執行完畢為空,回去了Event Queue讀取對應的函數,進入主線程。

上述過程會不斷重復,也就是常說的Event Loop(事件循環)。

但是,JS異步還有一個機制,就是遇到宏任務,先執行宏任務,將宏任務放入event queue,然后再執行微任務,將微任務放入eventqueue,但是,這兩個queue不是一個queue。當你往外拿的時候先從微任務里拿這個回調函數,然后再從宏任務的queue拿宏任務的回調函數,如下圖:

 

宏任務一般包括:整體代碼script,setTimeout,setInterval。

微任務:Promise,process.nextTick

參考文章: Javascript執行機制


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM