摘要:前段時(shí)間我對(duì)于瀏覽器中的和哪個(gè)先執(zhí)行有所困惑,苦于搜索也沒有發(fā)現(xiàn)很明確的答案,于是決定深入探索瀏覽器,現(xiàn)有所愚見,想與大家分享,希望能幫助到那些還在爬坑的人。瀏覽器端中的異步隊(duì)列有兩種隊(duì)列和隊(duì)列。瀏覽器會(huì)不斷從隊(duì)列中按順序取執(zhí)行。
前段時(shí)間我對(duì)于瀏覽器Event loop中的MacroTask和MicroTask哪個(gè)先執(zhí)行有所困惑,苦于搜索也沒有發(fā)現(xiàn)很明確的答案,于是決定深入探索瀏覽器Event loop,現(xiàn)有所愚見,想與大家分享,希望能幫助到那些還在爬坑的人。
1.什么是Event loop?
developer.mozilla.org給出的解釋是這樣的:
一個(gè) JavaScript 運(yùn)行時(shí)包含了一個(gè)待處理的消息隊(duì)列。每一個(gè)消息都關(guān)聯(lián)著一個(gè)用以處理這個(gè)消息的函數(shù)。
在事件循環(huán)期間的某個(gè)時(shí)刻,運(yùn)行時(shí)從最先進(jìn)入隊(duì)列的消息開始處理隊(duì)列中的消息。
大致可以理解為Event loop用來處理JavaScript事件執(zhí)行的先后順序。瀏覽器端Event loop中的異步隊(duì)列有兩種:MacroTask隊(duì)列和 MicroTask隊(duì)列。它們分別包括:
2.關(guān)于MacroTask和MicroTask。
MicroTask: process.nextTick ,promise ,MutationObserver,其中 process.nextTick 為 Node 獨(dú)有。 MacroTask: script(整體代碼),setTimeout ,setInterval ,setImmediate ,I/O ,UI rendering。
瀏覽器會(huì)不斷從task隊(duì)列中按順序取task執(zhí)行。
大體情況如下:
每執(zhí)行完一個(gè)Macrotask都會(huì)檢查microtask隊(duì)列是否為空,如果不為空則會(huì)一次性執(zhí)行完所有microtask。
3.同步事件和異步事件怎么處理?
一開始執(zhí)行棧空,micro 隊(duì)列空,macro 隊(duì)列里有且只有一個(gè) script 腳本(整體代碼)。然后全局上下文(script 標(biāo)簽)被推入執(zhí)行棧,同步代碼執(zhí)行。在執(zhí)行的過程中,會(huì)判斷是同步任務(wù)還是異步任務(wù),通過對(duì)一些接口的調(diào)用,可以產(chǎn)生新的 macro-task 與 micro-task,它們會(huì)分別被推入各自的任務(wù)隊(duì)列里。同步代碼執(zhí)行完了,script 腳本會(huì)被移出 macro 隊(duì)列,這個(gè)過程本質(zhì)上是隊(duì)列的 macro-task 的執(zhí)行和出隊(duì)的過程。需要注意的是:當(dāng) macro-task 出隊(duì)時(shí),任務(wù)是一個(gè)一個(gè)執(zhí)行的;而 micro-task 出隊(duì)時(shí),任務(wù)是一隊(duì)一隊(duì)執(zhí)行的。因此,我們處理 micro 隊(duì)列這一步,會(huì)逐個(gè)執(zhí)行隊(duì)列中的任務(wù)并把它出隊(duì),直到隊(duì)列被清空。
也就是說循環(huán)是這樣一個(gè)過程:
先執(zhí)行宏任務(wù),然后查看是否有微任務(wù)隊(duì)列。如果有,先執(zhí)行微任務(wù)隊(duì)列中的所有任務(wù),如果沒有,會(huì)讀取宏任務(wù)隊(duì)列中排在最前的任務(wù),執(zhí)行宏任務(wù)的過程中,遇到微任務(wù),依次加入微任務(wù)隊(duì)列。棧空后,再次讀取微任務(wù)隊(duì)列里的任務(wù)。
4:總結(jié)
一句話:
對(duì)于瀏覽器Event loop來說,由于script(整體代碼)先執(zhí)行,所以說MacroTask先于MicroTask執(zhí)行。
參考文章:
瀏覽器與Node的事件循環(huán)(Event Loop)有何區(qū)別?
一篇文章教會(huì)你Event loop
什么是瀏覽器的事件循環(huán)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/103928.html
摘要:對(duì)于通常的特別是那些具備并行計(jì)算多線程背景知識(shí)的來講,的異步處理著實(shí)稱得上詭異。而這個(gè)詭異從結(jié)果上講,是由的單線程這個(gè)特性所導(dǎo)致的。的特性之一是單線程,也即是從頭到尾,都在同一根線程下運(yùn)行。而這兩者的不同,便在于單線程和多線程上。 對(duì)于通常的developer(特別是那些具備并行計(jì)算/多線程背景知識(shí)的developer)來講,js的異步處理著實(shí)稱得上詭異。而這個(gè)詭異從結(jié)果上講,是由js...
摘要:回顧上一次參加還是年。年的還是真正的,年的會(huì)議早已經(jīng)把英文全稱去掉,改稱全球大前端技術(shù)大會(huì)。同時(shí)與產(chǎn)品協(xié)作從產(chǎn)品設(shè)計(jì)方面突出關(guān)注點(diǎn),做產(chǎn)品設(shè)計(jì)方面的優(yōu)化,如站新版改造減少頁面元素,將播放器窗口直接顯示在第一屏。 回顧 上一次參加 GMTC 還是 2017 年。那時(shí)的我還是剛剛參加工作并在試用期辭職的菜鳥。 2017 年的 GMTC 還是真正的 Global Mobile Tech Co...
摘要:階段有兩個(gè)主要功能也會(huì)執(zhí)行時(shí)間定時(shí)器到達(dá)期望時(shí)間的回調(diào)函數(shù)執(zhí)行事件循環(huán)列表里的函數(shù)當(dāng)進(jìn)入階段并且沒有其余的定時(shí)器,那么如果事件循環(huán)列表不為空,則迭代同步的執(zhí)行隊(duì)列中的函數(shù)。如果沒有,則等待回調(diào)函數(shù)進(jìn)入隊(duì)列并立即執(zhí)行。 Event Loop 本文以 Node.js 為例,講解 Event Loop 在 Node.js 的實(shí)現(xiàn),原文,JavaScript 中的實(shí)現(xiàn)大同小異。 什么是 Eve...
摘要:瀏覽器與的異同,以及部分機(jī)制有人對(duì)部分迷惑,本身構(gòu)造函數(shù)是同步的,是異步。瀏覽器的的已全部分析完成,過程中引用阮一峰博客,知乎,部分文章內(nèi)容,侵刪。 瀏覽器與NodeJS的EventLoop異同,以及部分機(jī)制 PS:有人對(duì)promise部分迷惑,Promise本身構(gòu)造函數(shù)是同步的,.then是異步。---- 2018/7/6 22:35修改 javascript 是一門單線程的腳本...
閱讀 2038·2023-04-26 01:33
閱讀 1666·2023-04-26 00:52
閱讀 1047·2021-11-18 13:14
閱讀 5453·2021-09-26 10:18
閱讀 2915·2021-09-22 15:52
閱讀 1495·2019-08-29 17:15
閱讀 3025·2019-08-29 16:11
閱讀 1044·2019-08-29 16:11