摘要:一句話解釋在事件循環(huán)機制中,有任務(wù)兩個隊列隊列和隊列。設(shè)置任務(wù)為目前運行的任務(wù),并執(zhí)行。應(yīng)該是考慮到了這一點,至少任務(wù)中的任務(wù),是被設(shè)置了在一個事件循環(huán)中的最大調(diào)用次數(shù)的,叫。參考材料理解事件循環(huán)
在Node學(xué)習(xí)過程中,不可避免的需要對事件循環(huán)機制做深入理解,其中Macrotask(大型任務(wù))和Microtask(小型任務(wù))比較令人困惑,在一番google之后,我發(fā)現(xiàn)了幾篇資料能比較好地解釋他們的原理。因此在這里匯總+搬運一下。
一句話解釋在Nodejs事件循環(huán)機制中,有任務(wù)兩個隊列:Macrotask隊列和Microtask隊列。在一個事件循環(huán)里,這兩個隊列會分兩步執(zhí)行,第一步會固定地執(zhí)行一個(且僅一個)Macrotask任務(wù),第二步會執(zhí)行整個Microtask隊列中的所有任務(wù)。并且,在執(zhí)行Microtask隊列任務(wù)的時候,也允許加入新的Microtask任務(wù),直到所有Microtask任務(wù)全部執(zhí)行完畢,才會結(jié)束循環(huán)。
Macrotasks一般包括: setTimeout, setInterval, setImmediate, I/O, UI rendering;
Microtasks一般包括: process.nextTick, Promises, Object.observe, MutationObserver。
從一個事件循環(huán)開始,到結(jié)束會經(jīng)歷以下步驟:
檢查Macrotask隊列,選擇其中最早加入(即最老的)的任務(wù)X,設(shè)置為“目前運行的任務(wù)”。如果任務(wù)X不存在,那么直接跳到步驟4。
運行任務(wù)X,即運行對應(yīng)的回調(diào)函數(shù)。
設(shè)置“目前運行的任務(wù)”為null,從Macrotask隊列中移除任務(wù)X。
檢查Microtask隊列:
1)選擇其中最老的任務(wù)a,如果任務(wù)a不存在,直接結(jié)束Microtask隊列。 2)設(shè)置任務(wù)a為“目前運行的任務(wù)”,并執(zhí)行。 3)設(shè)置“目前運行的任務(wù)”為null,從Microtask隊列中移除任務(wù)a。 4)選擇下一個最老的任務(wù)b,跳到步驟2)。 5)直到隊列里沒有剩余的任務(wù),結(jié)束隊列。
跳回步驟1,檢查下一個Macrotask任務(wù)。
關(guān)于事件循環(huán)步驟,參考文檔中的《理解 Node.js 事件循環(huán)》這篇文章講的非常好也非常詳細(xì),強烈推薦想了解的同學(xué)一定要看。
如何選用Macrotask或Microtask呢?可以這樣簡單理解:如果你想讓一個任務(wù)立即執(zhí)行,那么就把它設(shè)置為Microtask,除此之外都用Macrotask比較好。因為可以看出,雖然Node是異步非阻塞的,但在一個事件循環(huán)中,Microtask的執(zhí)行方式基本上就是用同步的。
可能存在的問題相信讀到這里你已經(jīng)意識到,如果一個Microtask隊列太長,或者執(zhí)行過程中不斷加入新的Microtask任務(wù),會導(dǎo)致下一個Macrotask任務(wù)很久都執(zhí)行不了。結(jié)果就是,你可能會遇到UI一直刷新不了,或者I/O任務(wù)一直完成不了。
應(yīng)該是考慮到了這一點,至少Microtask任務(wù)中的process.nextTick任務(wù),是被設(shè)置了(在一個事件循環(huán)中的)最大調(diào)用次數(shù)的,叫process.maxTickDepth。默認(rèn)是1000。一定程度上避免了上述情況。
參考材料理解 Node.js 事件循環(huán)
Difference between microtask and macrotask within an event loop context
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/91266.html
摘要:的單線程,與它的用途有關(guān)。事件循環(huán)事件循環(huán)是指主線程重復(fù)從消息隊列中取消息執(zhí)行的過程。到此為止,就完成了工作線程對主線程的通知,回調(diào)函數(shù)也就得到了執(zhí)行。 一. 區(qū)分進(jìn)程和線程 很多新手是區(qū)分不清線程和進(jìn)程的,沒有關(guān)系。這很正常。先看看下面這個形象的比喻: 進(jìn)程是一個工廠,工廠有它的獨立資源-工廠之間相互獨立-線程是工廠中的工人,多個工人協(xié)作完成任務(wù)-工廠內(nèi)有一個或多個工人-工人之間共享...
摘要:如果沒到毫秒,那么階段就會跳過,進(jìn)入階段,先執(zhí)行的回調(diào)函數(shù)。參考文檔什么是瀏覽器的事件循環(huán)不要混淆和瀏覽器中的定時器詳解瀏覽器和不同的事件循環(huán)深入理解事件循環(huán)機制篇中的執(zhí)行機制 最近對Event loop比較感興趣,所以了解了一下。但是發(fā)現(xiàn)整個Event loop盡管有很多篇文章,但是沒有一篇可以看完就對它所有內(nèi)容都了解的文章。大部分的文章都只闡述了瀏覽器或者Node二者之一,沒有對比...
摘要:瀏覽器和中并不一樣,瀏覽器的是在中定義的規(guī)范,而中則由庫實現(xiàn)。整個的這種運行機制又稱為事件循環(huán)例子了解瀏覽器的后,查看下面例子,猜測瀏覽器是怎么輸出的瀏覽器輸出中的在內(nèi)部有這樣一個事件環(huán)機制。在啟動時會初始化事件環(huán)。執(zhí)行和中到期的。 大家都知道,javascript是一門單線程語言,因此為了實現(xiàn)主線程的不阻塞,Event Loop這樣的方案應(yīng)運而生。 瀏覽器和node中Event lo...
摘要:瀏覽器渲染進(jìn)程瀏覽器內(nèi)核進(jìn)程,內(nèi)部是多線程的默認(rèn)每個頁面一個進(jìn)程,互不影響。事件觸發(fā)線程歸屬于瀏覽器而不是引擎,用來控制事件循環(huán)可以理解成引擎自己都忙不過來,需要瀏覽器另開線程協(xié)助。 線程和進(jìn)程 進(jìn)程和線程的概念可以這樣理解: 進(jìn)程是一個工廠,工廠有它的獨立資源--工廠之間相互獨立--線程是工廠中的工人,多個工人協(xié)作完成任務(wù)--工廠內(nèi)有一個或多個工人--工人之間共享空間 工廠有多個工人...
閱讀 647·2021-11-15 11:38
閱讀 1365·2021-10-11 10:59
閱讀 3556·2021-09-07 09:58
閱讀 551·2019-08-30 15:44
閱讀 3583·2019-08-28 18:14
閱讀 2664·2019-08-26 13:32
閱讀 3572·2019-08-26 12:23
閱讀 2475·2019-08-26 10:59