前段時間我對於瀏覽器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執行。
大致狀況以下:
函數
每執行完一個Macrotask都會檢查microtask隊列是否爲空,若是不爲空則會一次性執行完全部microtask。oop
3.同步事件和異步事件怎麼處理?post
一開始執行棧空,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執行。
參考文章: