1、基本概念
1. 所有同步任務都在主線程上執行,形成一個執行棧(execution context stack)。
2. 主線程之外,還存在一個“任務隊列”(task queue),隻要異步
任務有了運作結果,就在“任務隊列”中放置一個事件(包括事件綁定、ajax和定時器)。
3. 一旦“執行棧”中的所有同步任務執行完畢,系統就會讀取“任務隊
列”,看看裡邊有哪些事件。哪些對應的異步任務,于是結束等待
狀态,進入“執行棧”開始執行。
4. 主線程不斷重複上邊的第三步。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPB1kenR1T1sGROBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLxIDOwITNwcTM0EDMxkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
2、 如果添加了Promise又如何工作呢?
我們知道,Promise的回調函數不是傳入的,而是使用then來調用的。是以,Promise中定義的函數應該是馬上執行的,then才是其回調函數,放入queue隊列中。
在參考的文章中還提到了一個重要的概念:
macro-task包括:script(整體代碼), setTimeout, setInterval, setImmediate, I/O, UI rendering。
micro-task包括:process.nextTick, Promises, Object.observe, MutationObserver
執行順序:函數調用棧清空隻剩全局執行上下文,然後開始執行所有的micro-task。當所有可執行的micro-task執行完畢之後。循環再次執行macro-task中的一個任務隊列,執行完之後再執行所有的micro-task,就這樣一直循環。
再看一個例子:
(function test() {
setTimeout(function() {console.log(4)}, 0);
new Promise(function executor(resolve) {
console.log(1);
for( var i=0 ; i<10000 ; i++ ) {
i == 9999 && resolve();
}
console.log(2);
}).then(function() {
console.log(5);
});
console.log(3);
})()
具體的過程可以看上面那篇文章。大概過程如下:
- 遇到setTimeout,交給其他子產品執行,執行完後回調放入macro-task中
- 遇到Promise,立即執行裡面的function,輸出1。
- 循環開始,遇到resolve(),修改Promise狀态為fulfill。繼續執行,輸出2。
- 遇到then,将回調放入micro-task中。
- 繼續執行,輸出3。
- call stack執行完畢了。開始執行micro-task中的回調函數,輸出5。
- micro-task執行完畢,開始執行macro-task中的回調函數,輸出4。
- 結束。
原文連結:https://blog.csdn.net/qq_31628337/article/details/71056294
參考:https://blog.csdn.net/qq_31628337/article/details/71056294
http://www.ruanyifeng.com/blog/2014/10/event-loop.html