先以一道面試題做引子: 寫出這段程式的輸出內容: 如果你看了這道題不知道怎麼下手,或者發現結果和自己的答案大相徑庭,請繼續往下看 1. javascript事件迴圈首先,你要知道javascript是單線程語言。js任務需要排隊順序執行,如果一個任務耗時過長,後邊一個任務也的等著,但是,假如我們需要 ...
先以一道面試題做引子:
寫出這段程式的輸出內容:
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執行機制