深入分析下JS中的事件執行機制

2022-03-29 22:00:23
本篇文章通過分析一段程式碼的列印順序,帶大家深入瞭解一下javascript中的事件執行機制,希望對大家有所幫助!

前段時間一道筆試題,有點迷糊。今天徹底分析下JS的事件執行機制。【相關推薦:】

先看一段程式碼

各位小夥伴可以試著寫出列印順序

1.png

單執行緒

JS主要作為瀏覽器的指令碼語言,Js的主要用途是操作DOM,這就決定了JS必須是單執行緒,如果JS如Java一樣是多執行緒,如果兩個執行緒同時操作DOM,那麼瀏覽器應該怎麼執行呢?

JS的釋出其實是為了蹭Java的熱度,其中編寫這門語言的時間並不久,所以這也就是為什麼JS是單執行緒的原因

JS執行機制

JS既然是單執行緒,那麼必然會對任務進行一個排序。所有的任務都將按照一個規則執行下去。

  • 同步任務

  • 非同步任務

2.png

同步任務和非同步任務進入執行棧中,JS會先判斷任務的型別

  • 是同步任務,直接進入主執行緒

  • 是非同步任務,進入Event Table中,註冊回撥函數Event Queue

  • 同步任務全部執行結束,JS會Event Queue中讀取函數執行

  • 這個過程會反覆執行,直到全部任務執行結束。這就是我們常說的事件迴圈

JS如何判斷執行棧為空

emmmm,我不知道。。。。JS應該有一套自己獨有的邏輯去判斷執行棧是否為空。

非同步任務

非同步的任務執行順序為:宏任務——>微任務

非同步任務可分為

  • 宏任務

  • 微任務

常見的宏任務

  • I/0

  • setTimeout

  • setInterval

常見的微任務

  • Promise

  • .then

  • .catch

答案

vite 之前設定的一個外掛,版本有些問題,不要管這個紅色報警

3.png

分析

  • 開始了 是一個同步任務,最先進入執行棧中

  • 執行task()函數, a是一個同步任務,進入執行棧中

  • async/await 是非同步轉同步的過程,第一行程式碼會同步執行,以下的程式碼會非同步。b作為一個同步任務進入執行棧中

  • a end成為了非同步任務的微任務,進入執行棧中,

目前為止,同步任務佇列依次是 開始了, a, b

目前為止,非同步任務佇列依次是 宏任務: setTimeout 微任務:a end

如果沒有後續程式碼,列印順序如下

4.png

那麼問題來了,不是說宏任務會比微任務提前執行嗎,為什麼setTimeout列印在a end之後呢?

看這張圖

5.png

setTimeout 作為了宏任務進入了任務佇列。所以造成了這種原因

通俗來講:

async await 導致了微任務的產生,但是這個微任務所屬於當前的宏任務。所以會先執行a end,執行完畢判斷當前宏任務結束。執行下一個宏任務,列印出了setTimeout

繼續走流程

  • c 由於Promise的轉化,變為同步任務進入到任務佇列中

  • c end 作為Promise衍生的微任務進入任務佇列

  • d 作為同步任務進入任務佇列

目前為止,同步任務佇列

  • a

  • b

  • c

  • d

目前為止,非同步任務佇列

  • a end 微任務

  • c end 微任務

  • setTimeout 宏任務

所以列印順序如下

6.png

後記

自己對JS執行機制的理解,可能會有些不正確的地方,希望各位大佬指出。

【相關視訊教學推薦:】

以上就是深入分析下JS中的事件執行機制的詳細內容,更多請關注TW511.COM其它相關文章!