摘要:隊(duì)列分為兩種微任務(wù),中稱為。以下這些行為屬于微任務(wù)宏任務(wù),中稱為。因?yàn)楹耆蝿?wù)匯中包括了,瀏覽器會(huì)先執(zhí)行一個(gè)宏任務(wù),接下來(lái)有異步代碼的話就先執(zhí)行微任務(wù)。
在講Event loop之前,我們先思考一個(gè)問(wèn)題
js為什么是單線程?原因可能是如果js是多線程,在多個(gè)線程中處理DOM就可能會(huì)發(fā)生問(wèn)題(一個(gè)線程添加新節(jié)點(diǎn),另一個(gè)線程中刪除節(jié)點(diǎn)),當(dāng)然可以引入讀寫(xiě)鎖解決這個(gè)問(wèn)題
好了,接下來(lái)我們開(kāi)始講Event loop
簡(jiǎn)單的說(shuō),就是js在執(zhí)行的過(guò)程中會(huì)產(chǎn)生執(zhí)行環(huán)境,這些執(zhí)行環(huán)境會(huì)被順序的加入到執(zhí)行棧中。如果遇到異步的代碼,會(huì)被掛起并加入到Task(有多種Task)隊(duì)列中。一旦執(zhí)行棧為空,Event Loop就會(huì)從Task隊(duì)列中拿出需要執(zhí)行的代碼并放入執(zhí)行棧中執(zhí)行,所以本質(zhì)上來(lái)說(shuō),js中的異步行為還是同步的。
我們看下以下代碼,以下代碼輸出"1", "3", "2"
console.log("1"); setTimeout(()=>{ console.log("2"); }, 0); console.log("3"); //"1" //"3" //"2"
之前對(duì)setTimeout理解有偏差,雖然設(shè)置了為0,其實(shí)還是異步,是因?yàn)閔tml5標(biāo)準(zhǔn)規(guī)定這個(gè)函數(shù)的第二個(gè)參數(shù)不得小于4ms,不足會(huì)自動(dòng)增加。
Task隊(duì)列分為兩種
微任務(wù)microtask,es6中稱為jobs。以下這些行為屬于微任務(wù)
process.nextTick
promise
Object.observe
MutationObserver
宏任務(wù)macrotask,es6中稱為task。以下這些行為屬于宏任務(wù)
script
setTimeout
setInterval
setImmediate
I/O
UI rendering
誤區(qū):很多人認(rèn)為微任務(wù)快于宏任務(wù),其實(shí)是錯(cuò)誤的。因?yàn)楹耆蝿?wù)匯中包括了script,瀏覽器會(huì)先執(zhí)行一個(gè)宏任務(wù),接下來(lái)有異步代碼的話就先執(zhí)行微任務(wù)。
正確的一次Event loop順序應(yīng)該是這樣的:
執(zhí)行同步代碼(這屬于宏任務(wù))
執(zhí)行棧為空,查詢是否有微任務(wù)需要執(zhí)行
執(zhí)行所有微任務(wù)
必要的話渲染UI
開(kāi)始下一輪Event loop,執(zhí)行宏任務(wù)中的異步代碼
通過(guò)上述的Event loop順序可知,如果宏任務(wù)中的異步代碼有大量的計(jì)算并且需要操作DOM的話,為了更快的界面響應(yīng),我們可以把操作DOM放入微任務(wù)中。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96543.html
摘要:如果沒(méi)到毫秒,那么階段就會(huì)跳過(guò),進(jìn)入階段,先執(zhí)行的回調(diào)函數(shù)。參考文檔什么是瀏覽器的事件循環(huán)不要混淆和瀏覽器中的定時(shí)器詳解瀏覽器和不同的事件循環(huán)深入理解事件循環(huán)機(jī)制篇中的執(zhí)行機(jī)制 最近對(duì)Event loop比較感興趣,所以了解了一下。但是發(fā)現(xiàn)整個(gè)Event loop盡管有很多篇文章,但是沒(méi)有一篇可以看完就對(duì)它所有內(nèi)容都了解的文章。大部分的文章都只闡述了瀏覽器或者Node二者之一,沒(méi)有對(duì)比...
摘要:任務(wù)隊(duì)列中的任務(wù)事件,一般有個(gè)共性就是存在回調(diào)函數(shù)。存放異步執(zhí)行的代碼,如定時(shí)器事件監(jiān)聽(tīng)回調(diào)函數(shù)等,進(jìn)入等待狀態(tài)。總結(jié)的事件輪詢的機(jī)制,使任務(wù)隊(duì)列主線程異步操作之間可以相互協(xié)作。 從一道面試題說(shuō)起 setTimeout(function() { console.log(111); }, 0); // 這里定時(shí)器時(shí)間設(shè)置為0ms后執(zhí)行 console.log(222); 相信這...
摘要:下面我將介紹的基本用法以及如何在異步編程中使用它們。在沒(méi)有發(fā)布之前,作為異步編程主力軍的回調(diào)函數(shù)一直被人詬病,其原因有太多比如回調(diào)地獄代碼執(zhí)行順序難以追蹤后期因代碼變得十分復(fù)雜導(dǎo)致無(wú)法維護(hù)和更新等,而的出現(xiàn)在很大程度上改變了之前的窘境。 前言 自己著手準(zhǔn)備寫(xiě)這篇文章的初衷是覺(jué)得如果想要更深入的理解 JS,異步編程則是必須要跨過(guò)的一道坎。由于這里面涉及到的東西很多也很廣,在初學(xué) JS 的...
原文 先說(shuō)1.1總攬: Reactor模式 Reactor模式中的協(xié)調(diào)機(jī)制Event Loop Reactor模式中的事件分離器Event Demultiplexer 一些Event Demultiplexer處理不了的復(fù)雜I/O接口比如File I/O、DNS等 復(fù)雜I/O的解決方案 未完待續(xù) 前言 nodejs和其他編程平臺(tái)的區(qū)別在于如何去處理I/O接口,我們聽(tīng)一個(gè)人介紹nodejs,總是...
摘要:下面開(kāi)始分析開(kāi)頭的代碼第一輪事件循環(huán)流程整體作為第一個(gè)宏任務(wù)進(jìn)入主線程,遇到,輸出遇到函數(shù)聲明,聲明暫時(shí)不用管遇到,其回調(diào)函數(shù)被分發(fā)到微任務(wù)中。我們記為遇到,其回調(diào)函數(shù)被分發(fā)到宏任務(wù)中。 先上一道常見(jiàn)的筆試題 console.log(1); async function async1() { console.log(2); await async2(); con...
閱讀 3585·2021-10-11 10:59
閱讀 1601·2021-09-29 09:35
閱讀 2269·2021-09-26 09:46
閱讀 3785·2021-09-10 10:50
閱讀 961·2019-08-29 12:17
閱讀 830·2019-08-26 13:40
閱讀 2443·2019-08-26 11:44
閱讀 2116·2019-08-26 11:22