JavaScript核心之事件循環

基本概念

  1. 宿主環境javascript

    • JS所在的運行環境,通常爲瀏覽器,但也有其它的宿主環境,例如:node;
    • 每一個宿主環境都會提供不一樣的API供JS調用,如windowdocumentsetTimeout、脫離瀏覽器就不會有這些API。
  2. JS執行引擎:JS宿主環境中的一個功能模塊,用於解析並執行JS代碼。
  3. 瀏覽器中的功能模塊:一個模塊佔用一個線程。java

    • JS執行引擎
    • 計時器
    • 網絡請求
    • 頁面渲染
    • 事件監聽
> JS是單線程的緣由是瀏覽器只會開一個JS執行引擎
  1. 異步代碼:同一個線程裏面的代碼都是同步執行的,只有新開一個線程才能執行異步代碼,因此只有瀏覽器提供的setTimeout,promise等能夠調用其它線程的API才能執行異步代碼。

事件隊列

用於存放執行棧清空後執行的異步代碼,一般從計時器、網絡請求、事件監聽等其它線程中獲取。node

事件循環

  1. JS代碼只能在執行引擎中執行,每次執行一個函數都會將函數推入執行棧(具體內容能夠查看文章:JavaScript核心之執行上下文);
  2. 代碼執行過程當中遇到setTimeout等函數時,會調用宿主中的其它線程(計時器);
  3. 其它線程中的函數執行完成事後,如計時器計時完成後,會將回調函數加入事件隊列;
  4. 待執行棧全部同步代碼執行完,執行棧清空後,JS引擎回去事件隊列中看看有沒有要執行的代碼,有的話就入棧執行。

圖解:
微信截圖_20200203115944.pngsegmentfault

舉個例子:這裏以setTimeout爲例,其它異步方法都是同樣的promise

setTimeout(function bar(){
    console.log('計時器回調執行');
}, 0)

function foo(){
    console.log('foo函數執行');
}

foo();
//執行過程僞代碼:
1. 執行棧入棧setTimeout函數;
執行棧:[setTimeout]
計時線程:[]
事件隊列:[]

2. 瀏覽器遇到其它線程API,通知對應線程執行代碼,此時瀏覽器喚起的是計時器線程,將setTimeout方法推入計時器線程;
執行棧:[]
計時線程:[setTimeout]
事件隊列:[]

3. 執行棧繼續執行後續代碼,入棧foo函數,同時,計時線程中的setTimeout在計時;
執行棧:[foo]
計時線程:[setTimeout]
事件隊列:[]

4. 計時完畢,計時線程將setTime方法的回調函數推入事件隊列,而後計時器線程中的setTimeout執行完畢被銷燬;
執行棧:[foo]
計時線程:[]
事件隊列:[bar]

5. 執行foo函數,打印'foo函數執行',foo執行完畢,foo函數出棧;
執行棧:[]
計時線程:[]
事件隊列:[bar]

6. 執行棧沒有可執行代碼,會隔一段時間去事件隊列中查看(事件輪詢)一下有沒有可執行代碼,此時查看到有一個bar函數,將bar函數推入執行棧;
執行棧:[bar]
計時線程:[]
事件隊列:[]

7. 執行bar函數,打印'計時器回調執行',bar執行完畢,bar函數出棧;
執行棧:[]
計時線程:[]
事件隊列:[]

從上述例子能夠看出:瀏覽器

  1. setTimeout的計時並不許確,計時完成後只是將回調函數推入事件隊列,並非立刻執行,還要等執行棧清空後纔會執行;
  2. 無論setTimeout的方法是否是寫在最前面,計時時間有多短,都是在同步代碼執行完畢後纔會執行。

宏隊列,微隊列

事件隊列又能夠細分爲宏隊列和微隊列,每次執行棧清空後會先執行微隊列中的任務,再執行宏隊列中的任務;微信

  • 宏隊列任務:計時器、網絡請求、dom事件
  • 微隊列任務:Promise.thenmutationObserver

舉個例子:網絡

setTimeout(function(){
    console.log('計時完成'); //3. 最後執行宏任務中的隊列
}, 0);

new Promise(function(resolve, reject){
    console.log('promise 代碼執行'); //1. 先執行,這裏的代碼是同步的
    resolve();
}).then(function(){
    console.log('promise resolve'); //2. 執行棧空了以後,先執行微隊列中的任務
})
無論宏任務中的代碼寫在哪裏,都是在微任務執行後再執行。由於瀏覽器會在微隊列清空後再去看宏隊列。
相關文章
相關標籤/搜索