詳細示例,講解事件循環(Event Loop)機制,看這一篇就夠了。

1.瀏覽器中的線程有以下幾種:

  • js執行線程
  • GUI渲染線程
  • 事件監聽線程
  • 計時器計時線程
  • 網絡通信線程

2.如何理解js單線程?

之所以說js單線程,是因爲它的執行引擎只有一個線程,並且不會在執行期間開啓新的線程。而並非是指瀏覽器單線程。

3.js執行棧

js線程執行任務時,會創建js執行棧。同步任務直接推入執行棧中執行,異步任務推入事件隊列中,註冊回調函數。當執行棧空閒時,js會去事件隊列中讀取事件當初註冊的回調函數,到執行棧中,並執行函數。

4.事件隊列劃分

  • 宏隊列:script, settimeout,ajax請求,dom事件
  • 微隊列:Promise.then、MutationObserver

當執行棧空閒時,js首先會將微隊列中的所有微任務執行完,再去執行宏隊列中的宏任務。

一輪循環是這樣的:當js執行時,先執行宏任務,遇到微任務,則推入微隊列,並註冊回調函數。當所有宏任務執行完後,會讀取微任務註冊的回調函數到執行棧中執行。執行完後。繼續下一輪循環

看下面這個示例:

setTimeout(function () {
  console.log('three');
}, 0);

Promise.resolve().then(function () {
  console.log('two');
});

console.log('one');
結果:
// one
// two
// three

分析:

  • 首先整段代碼可以看做是宏任務

  • 當js執行時,遇到setTimeout,它是宏任務,則放入宏隊列,等待本輪執行完後,在一輪循環中執行。然後遇到了promise的then,則被推入微隊列。

  • 接着,打印one。好了,到此,本輪所有的宏任務已經執行完畢,但是,本次循環並未結束。

  • 然後,js去微隊列中讀取then註冊的回調函數執行,打印two

  • 注意了!!!到此,本輪所有任務執行完畢,本次事件循環結束了。

  • 接着,開啓下一輪循環,執行settimeout,打印three。所以,輸出結果爲:

one
two
three
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章