js事件循環(huán) Event Loop的簡單理解(一)

5分鐘看完文章,即可解決大部分執(zhí)行順序的題目,那些題都是跟事件循環(huán)機(jī)制有關(guān)。(個(gè)人水平有限咯,如有錯(cuò)誤歡迎指出)
之前寫過一篇,宏任務(wù)與微任務(wù)的執(zhí)行順序,但是這不是根本,今天我覺得很有必要講一下event loop。
進(jìn)入正題,地球人都知道js是單線程。那么它可能存在執(zhí)行任務(wù)時(shí)候任務(wù)阻塞,Event Loop的出現(xiàn),就是完美的解決了這個(gè)問題。

1、首先我們知道js代碼執(zhí)行分為同步任務(wù)異步任務(wù)

同步: script代碼塊(如console.log)
異步又分為:
宏任務(wù):setTimeoutI/O
微任務(wù):promise.then()、async的awaitnew MutationObserver()

我們可以看到它的異步又分為宏任務(wù)與微任務(wù)(面試中經(jīng)常提到的執(zhí)行順序)。

2、調(diào)用棧和任務(wù)隊(duì)列

隊(duì)列的執(zhí)行順序
請(qǐng)看下面圖例,js執(zhí)行任務(wù)時(shí)候,有個(gè)調(diào)用棧用來執(zhí)行代碼,兩個(gè)任務(wù)隊(duì)列(宏任務(wù)、微任務(wù)),A、B是兩個(gè)函數(shù)。


很容易理解,棧是先進(jìn)后出,而隊(duì)列則不同,是先進(jìn)先出。
到這里對(duì)事件循環(huán)的基礎(chǔ)了解有了60%。接下來就了解知道它是大概怎么執(zhí)行循環(huán)的。

3、事件循環(huán) Event Loop執(zhí)行順序(重點(diǎn))

上面列舉的代碼模塊按照一定的機(jī)制循環(huán)執(zhí)行,就是Event Loop,也叫事件循環(huán)。
要了解它的執(zhí)行順序有兩點(diǎn):
1、js是在調(diào)用棧里面執(zhí)行,執(zhí)行時(shí)代碼分為同步任務(wù)異步任務(wù)。同步的先執(zhí)行,執(zhí)行完了再執(zhí)行異步任務(wù)代碼。為什么?可以理解為不清楚異步是什么時(shí)候執(zhí)行完成的,所以同步代碼先執(zhí)行。
2、接第一點(diǎn),同步代碼全部執(zhí)行完后才開始執(zhí)行異步,異步里微任務(wù)比宏任務(wù)先執(zhí)行(理解為微任務(wù)執(zhí)行比較快,為了方便你記憶),直到微任務(wù)隊(duì)列沒了,才去執(zhí)行宏任務(wù)。

假設(shè)有如下代碼塊,我們按照上面的

setTimeout(() => {
    console.log(1);
}, 0)
console.log(2)
new Promise((resolve) => {
    resolve(3)
}).then(res => console.log(res))
function foo() {
    console.log(4);
}
foo()
new Promise((resolve) => {
    resolve(6)
}).then(res => console.log(res))

這個(gè)代碼塊,執(zhí)行時(shí),第一輪結(jié)束時(shí)候,會(huì)是如下結(jié)果(所有代碼都會(huì)進(jìn)入執(zhí)行棧里執(zhí)行時(shí)候彈出,這個(gè)過程不畫了):

第一輪

同步任務(wù)全部執(zhí)行完畢,直接在控制臺(tái)分別打印 2 ---- 4 ,(其實(shí)執(zhí)行期間)異步任務(wù)會(huì)分別被分配到宏任務(wù)隊(duì)列微任務(wù)隊(duì)列,此時(shí)開始執(zhí)行下一輪的任務(wù)事件,第二輪,我們來看下,它的圖解:
第二輪

微任務(wù)console.log(3)進(jìn)入執(zhí)行棧,然后彈出,所以在控制臺(tái)先輸出3,然后再檢查是否有微任務(wù),console.log(6)再進(jìn)入執(zhí)行棧,然后彈出,控制臺(tái)輸出6。
接著第三輪,就是剩下宏任務(wù)了,運(yùn)行宏任務(wù)隊(duì)列代碼塊console.log(1),控制臺(tái)輸出1。
所以最終結(jié)果就是:2---4---3---6---1

看到這里了解了嗎?代碼按規(guī)律循環(huán)執(zhí)行這就是 事件循環(huán)Event Loop,有沒有很簡單。

但是但是但是,如果只會(huì)這點(diǎn)的話不行啦,遇到稍微復(fù)雜一點(diǎn)的循環(huán)就有點(diǎn)蒙,而且,有坑點(diǎn)。請(qǐng)看我這篇文章:

js事件循環(huán)簡單理解,微任務(wù)與宏任務(wù)運(yùn)行順序(二)

看完你會(huì)回來感謝我的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容