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