先以一道面試題作引子:javascript
寫出這段程序的輸出內容:java
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任務須要排隊順序執行,若是一個任務耗時過長,後邊一個任務也的等着,可是,假如咱們須要瀏覽新聞,但新聞包含的超清圖片加載很慢,總不能網頁一直卡着直到圖片徹底出來,因此將任務設計成了兩類:異步
同步任務
異步任務
當咱們打開網站時,網頁的渲染過程就是一大堆同步任務,像頁面骨架和頁面元素的渲染,而加載圖片、音樂之類的任務就是異步任務,看一下下邊導圖:函數
如圖:oop
同步和異步任務分別進入不一樣的執行「場所」,同步進入主線程,異步進入Event Table並註冊函數。當指定的事情完成時,Event Table會將這個函數移入Event Queue。主線程內的任務執行完畢爲空,回去了Event Queue讀取對應的函數,進入主線程。post
上述過程會不斷重複,也就是常說的Event Loop(事件循環)。網站
可是,JS異步還有一個機制,就是遇到宏任務,先執行宏任務,將宏任務放入event queue,而後再執行微任務,將微任務放入eventqueue,可是,這兩個queue不是一個queue。當你往外拿的時候先從微任務裏拿這個回調函數,而後再從宏任務的queue拿宏任務的回調函數,以下圖:spa
宏任務通常包括:總體代碼script,setTimeout,setInterval。線程
微任務:Promise,process.nextTick
參考文章: Javascript執行機制