js-Event Loop

什么是Event Loop?

js是單線程語言,代碼需要一句一句往下執(zhí)行粘秆,會(huì)出現(xiàn)阻塞粹胯。Event Loop是解決這一問題的機(jī)制,讓js實(shí)現(xiàn)異步蒋困,在不同的js執(zhí)行環(huán)境中(瀏覽器盾似、node)表現(xiàn)不同。

瀏覽器中的Event Loop

js自上而下執(zhí)行代碼
同步任務(wù)雪标,在調(diào)用棧中按照順序等待主線程依次執(zhí)行
異步任務(wù)零院,在EventTable中注冊回調(diào)事件,等異步任務(wù)有結(jié)果后村刨,將注冊的回調(diào)函數(shù)放入對應(yīng)的任務(wù)隊(duì)列中

任務(wù)隊(duì)列有宏任務(wù)隊(duì)列和微任務(wù)隊(duì)列告抄。

一個(gè)線程僅有一個(gè)微任務(wù)隊(duì)列,微任務(wù)包括:promise.then/catch/final嵌牺、Mutation Observer打洼、process.nextTick(node)龄糊。除此之外的事件,均為宏任務(wù)募疮。

一個(gè)線程可以有多個(gè)宏任務(wù)隊(duì)列分別處理不同類型的事件炫惩,如鼠標(biāo)鍵盤事件可放在一個(gè)宏任務(wù)隊(duì)列中,優(yōu)先執(zhí)行保證用戶體驗(yàn)阿浓,其他類型事件可分別放在不同的宏任務(wù)隊(duì)列中他嚷。

執(zhí)行順序:一個(gè)宏任務(wù) -> 全部微任務(wù) -> 一個(gè)宏任務(wù) -> 全部微任務(wù) -> ...直至兩個(gè)隊(duì)列都為空。同步任務(wù)相當(dāng)于一個(gè)宏任務(wù)芭毙,在最開始執(zhí)行筋蓖。

  • promise.xxx屬于es6范疇,規(guī)范中對于其是否視為微任務(wù)并不明晰退敦,所以各瀏覽器實(shí)現(xiàn)上有所不同粘咖,影響執(zhí)行順序。Google將其視為微任務(wù)侈百,Safari和Firefox將其視為宏任務(wù)瓮下。

  • async await是promise的語法糖,可轉(zhuǎn)為promise.then來看待设哗。

node中的Event Loop

node的Event Loop一共分為6個(gè)階段唱捣,每個(gè)細(xì)節(jié)具體如下:

  • timers:本階段執(zhí)行已經(jīng)被 setTimeout() 和 setInterval() 的調(diào)度回調(diào)函數(shù)。
  • pending callbacks:執(zhí)行延遲到下一個(gè)循環(huán)迭代的 I/O 回調(diào)网梢。
  • idle, prepare:僅系統(tǒng)內(nèi)部使用震缭。
  • poll:檢索新的 I/O 事件;執(zhí)行與 I/O 相關(guān)的回調(diào)(幾乎所有情況下,除了關(guān)閉的回調(diào)函數(shù)战虏,那些由計(jì)時(shí)器和 setImmediate() 調(diào)度的之外)拣宰,其余情況 node 將在適當(dāng)?shù)臅r(shí)候在此阻塞。
  • check:setImmediate() 回調(diào)函數(shù)在這里執(zhí)行烦感。
  • close callbacks:一些關(guān)閉的回調(diào)函數(shù)巡社,如:socket.on('close', ...)。
   ┌───────────────────────────┐
┌─>│           timers          │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │     pending callbacks     │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │       idle, prepare       │
│  └─────────────┬─────────────┘      ┌───────────────┐
│  ┌─────────────┴─────────────┐      │   incoming:   │
│  │           poll            │<─────┤  connections, │
│  └─────────────┬─────────────┘      │   data, etc.  │
│  ┌─────────────┴─────────────┐      └───────────────┘
│  │           check           │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
└──┤      close callbacks      │
   └───────────────────────────┘

process.nextTick事件單獨(dú)有一個(gè)隊(duì)列存放手趣,當(dāng)每一階段執(zhí)行完畢后晌该,先執(zhí)行process.nextTick queue里的全部,再執(zhí)行micro queue里的全部绿渣,然后再進(jìn)入下一階段朝群。

為了和瀏覽器更加趨同,node v11版本將timer階段的setTimeout,setInterval...和在check階段的immediate改為一旦執(zhí)行一個(gè)階段里的一個(gè)任務(wù)就立刻執(zhí)行微任務(wù)隊(duì)列中符。node v10版本還是保持自己的執(zhí)行方式姜胖。

對比總結(jié)

瀏覽器環(huán)境下,microtask 的任務(wù)隊(duì)列是每個(gè) macrotask 執(zhí)行完之后執(zhí)行淀散。而在 Node.js 中右莱,microtask 會(huì)在事件循環(huán)的各個(gè)階段之間執(zhí)行蚜锨,也就是一個(gè)階段執(zhí)行完畢,就會(huì)去執(zhí)行 microtask 隊(duì)列的任務(wù)慢蜓。

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末亚再,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子胀瞪,更是在濱河造成了極大的恐慌针余,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凄诞,死亡現(xiàn)場離奇詭異,居然都是意外死亡忍级,警方通過查閱死者的電腦和手機(jī)帆谍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來轴咱,“玉大人汛蝙,你說我怎么就攤上這事∑臃危” “怎么了窖剑?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長戈稿。 經(jīng)常有香客問我西土,道長,這世上最難降的妖魔是什么鞍盗? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任需了,我火速辦了婚禮,結(jié)果婚禮上般甲,老公的妹妹穿的比我還像新娘肋乍。我一直安慰自己,他們只是感情好敷存,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布墓造。 她就那樣靜靜地躺著,像睡著了一般锚烦。 火紅的嫁衣襯著肌膚如雪觅闽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天挽牢,我揣著相機(jī)與錄音谱煤,去河邊找鬼。 笑死禽拔,一個(gè)胖子當(dāng)著我的面吹牛刘离,可吹牛的內(nèi)容都是我干的室叉。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼硫惕,長吁一口氣:“原來是場噩夢啊……” “哼茧痕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起恼除,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤踪旷,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后豁辉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體令野,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年徽级,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了气破。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡餐抢,死狀恐怖现使,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情旷痕,我是刑警寧澤碳锈,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站欺抗,受9級特大地震影響售碳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜佩迟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一团滥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧报强,春花似錦灸姊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至召嘶,卻和暖如春父晶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背弄跌。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工甲喝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人铛只。 一個(gè)月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓埠胖,卻偏偏與公主長得像糠溜,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子直撤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容