簡潔明瞭探索瀏覽器Event loop

前段時間我對於瀏覽器Event loop中的MacroTask和MicroTask哪一個先執行有所困惑,苦於搜索也沒有發現很明確的答案,因而決定深刻探索瀏覽器Event loop,現有所愚見,想與你們分享,但願能幫助到那些還在爬坑的人。
1.什麼是Event loop?segmentfault

developer.mozilla.org給出的解釋是這樣的:promise

一個 JavaScript 運行時包含了一個待處理的消息隊列。每個消息都關聯着一個用以處理這個消息的函數。

在事件循環期間的某個時刻,運行時從最早進入隊列的消息開始處理隊列中的消息。瀏覽器

大體能夠理解爲Event loop用來處理JavaScript事件執行的前後順序。瀏覽器端Event loop中的異步隊列有兩種:MacroTask隊列和 MicroTask隊列。它們分別包括:

2.關於MacroTask和MicroTask。異步

MicroTask: process.nextTick ,promise ,MutationObserver,其中 process.nextTick 爲 Node 獨有。
MacroTask: script(總體代碼),setTimeout ,setInterval ,setImmediate ,I/O ,UI rendering。

瀏覽器會不斷從task隊列中按順序取task執行。
大致狀況以下:
clipboard.png函數

每執行完一個Macrotask都會檢查microtask隊列是否爲空,若是不爲空則會一次性執行完全部microtask。oop

3.同步事件和異步事件怎麼處理?post

clipboard.png

一開始執行棧空,micro 隊列空,macro 隊列裏有且只有一個 script 腳本(總體代碼)。而後全局上下文(script 標籤)被推入執行棧,同步代碼執行。在執行的過程當中,會判斷是同步任務仍是異步任務,經過對一些接口的調用,能夠產生新的 macro-task 與 micro-task,它們會分別被推入各自的任務隊列裏。同步代碼執行完了,script 腳本會被移出 macro 隊列,這個過程本質上是隊列的 macro-task 的執行和出隊的過程。須要注意的是:當 macro-task 出隊時,任務是一個一個執行的;而 micro-task 出隊時,任務是一隊一隊執行的。所以,咱們處理 micro 隊列這一步,會逐個執行隊列中的任務並把它出隊,直到隊列被清空。spa

也就是說循環是這樣一個過程:
先執行宏任務,而後查看是否有微任務隊列。若是有,先執行微任務隊列中的全部任務,若是沒有,會讀取宏任務隊列中排在最前的任務,執行宏任務的過程當中,遇到微任務,依次加入微任務隊列。棧空後,再次讀取微任務隊列裏的任務。code

4:總結
一句話:server

對於瀏覽器Event loop來講,因爲script(總體代碼)先執行,因此說MacroTask先於MicroTask執行。

參考文章:

瀏覽器與Node的事件循環(Event Loop)有何區別?
一篇文章教會你Event loop
什麼是瀏覽器的事件循環

相關文章
相關標籤/搜索