Event Loop of Javascript

  1. js是單線程的荆针?與異步矛盾嘛碑宴?

不矛盾,因?yàn)閖s執(zhí)行是單線程的姐叁,但是瀏覽器是多線程的瓦盛。其中的異步是靠瀏覽器是開新的進(jìn)程去執(zhí)行的。其中是依靠libuv
其的單線程是:一個(gè)瀏覽器中只有一個(gè)js的執(zhí)行線程外潜,同一時(shí)刻也只有一個(gè)js文件在執(zhí)行谭溉,其會(huì)阻塞其他任務(wù)的進(jìn)行。

先寫點(diǎn)東西橡卤,
瀏覽器是多線程的,一般會(huì)有以下幾個(gè)常駐的線程在運(yùn)行

  • GUI render thread
  • JS engine thread (也就是下文所說的主線程)
  • asnyc http request thread
  • setTimeout thread
  • Event target thread
  • Event loop thread 這個(gè)是瀏覽器的主線程损搬,其是一個(gè)無限循環(huán)碧库,永遠(yuǎn)處于接受處理的狀態(tài),并等待事件(如布局和繪制事件)發(fā)生巧勤,并進(jìn)行處理嵌灰。
    瀏覽器是事件驅(qū)動(dòng)的(event driven),其的很多行為會(huì)創(chuàng)建異步事件,然后將其加入到任務(wù)隊(duì)列中去颅悉。

當(dāng)js在解析過程中沽瞭,碰見一些異步情況,如Ajax剩瓶,setTimeout.etc驹溃,會(huì)
一個(gè)chrome瀏覽器的一個(gè)tab page中有一個(gè)不斷循環(huán)的線程,叫做Event loop延曙。其貫穿頁面的開啟和關(guān)閉豌鹤。還有相關(guān)若干的線程,如GUI render thread枝缔、JS engine thread 布疙、setTimeout thread、Event target thread愿卸、async http request thread灵临,其中GUI和js thread是相斥的,一個(gè)運(yùn)行會(huì)阻塞別一個(gè)運(yùn)行趴荸。然后因?yàn)閖s是單線程的儒溉,然后這個(gè)js engine thread 會(huì)調(diào)用一個(gè)子線程去運(yùn)行js代碼,然后其他的線程去忙別的事情赊舶。

單線程的js在解析代碼的時(shí)候睁搭,會(huì)將demo以call stack 進(jìn)行解析赶诊。在不斷的解析過程中,碰見異步的情況园骆,js去調(diào)用web的apis舔痪,這個(gè)時(shí)候,就是讓瀏覽器中其他的線程去完成異步情況锌唾。當(dāng)其他的線程完成異步情況之后锄码,將這個(gè)完成情況(也就是通常所說的消息,也指向回調(diào)函數(shù))插入任務(wù)隊(duì)列晌涕。然后等到執(zhí)行棧沒有任務(wù)的時(shí)候滋捶,eventLoop會(huì)將任務(wù)隊(duì)列的任務(wù)給推到執(zhí)行棧中進(jìn)行執(zhí)行。
同時(shí)也解釋了為什么setTimeout(function(){},0)余黎,也不能直接involve 回調(diào)函數(shù)重窟。因?yàn)閟etTimeout是個(gè)異步過程。只有當(dāng)call stack中的任務(wù)運(yùn)行結(jié)束之后惧财,才會(huì)在callback queue中去調(diào)用setTimeout的callback function巡扇。

eventLoop.png

reference
可視化js工作流程
reference

中文文檔和blog真的有時(shí)候不行,浪費(fèi)了我一天的時(shí)間去弄懂這些垮衷√瑁看完英語的,一個(gè)小時(shí)就搞懂了搀突。mmp刀闷。

Update ??

原來不光有Event Loop,還有microTask仰迁,macroTask甸昏,在去真的了解Promise才發(fā)現(xiàn)的。
下圖中的taskQueue就是macrotask徐许。
其中macroTask和microTask是兩種任務(wù)隊(duì)列筒扒,在上文中,是大致介紹javascript Engine的流程绊寻,但是并沒有對(duì)其中的task queue進(jìn)行劃分花墩。相比而言,大家更熟悉的一個(gè)詞是任務(wù)隊(duì)列(task queue,其實(shí)就是macroTask),大家更熟悉的關(guān)于事件循環(huán)的機(jī)制說法大概是:主進(jìn)程執(zhí)行完了之后澄步,每次從任務(wù)隊(duì)列里取一個(gè)任務(wù)執(zhí)行冰蘑。但是promise出現(xiàn)之后,這個(gè)說法就不太準(zhǔn)確了村缸。
JavaScript引擎對(duì)這兩種隊(duì)列有不同的處理祠肥,簡(jiǎn)單的說就是引擎會(huì)把我們的所有任務(wù)分門別類,一部分歸為macroTask梯皿,另外一部分歸為microTask仇箱,下面是類別劃分:

  • macroTask: setTimeout, setInterval, setImmediate, requestAnimationFrame, I/O, UI rendering,平時(shí)的script中的代碼
  • microTask: process.nextTick, Promise, Object.observe, MutationObserver

我們所熟悉的定時(shí)器就屬于macroTask县恕,但是僅僅了解macroTask的機(jī)制還是不夠的。
update:2018-8-25 其中在js中剂桥,對(duì)于macroTask和microTask的處理是不一樣的忠烛,如下圖

image.png

為此總結(jié)一句口訣:代碼運(yùn)行就是宏,遇見new Promise()就執(zhí)行权逗,then放microTask中后執(zhí)行美尸,process.nextTick()等microTask,看進(jìn)入taskQueue順序斟薇,畢竟是隊(duì)列师坎,先進(jìn)先出,setTimeout最后來堪滨。
強(qiáng)烈推薦看這個(gè)
promise/A+規(guī)范
detailsOfEventLoop.png

reference
reference1
從Promise來看JavaScript中的Event Loop胯陋、Tasks和Microtasks
理解事件循環(huán)二(macrotask和microtask)

nodejs construction

nodejs.png

帶你領(lǐng)略Nodejs前世今生

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市袱箱,隨后出現(xiàn)的幾起案子惶岭,更是在濱河造成了極大的恐慌,老刑警劉巖犯眠,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異症革,居然都是意外死亡筐咧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門噪矛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來量蕊,“玉大人,你說我怎么就攤上這事艇挨〔信冢” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵缩滨,是天一觀的道長(zhǎng)势就。 經(jīng)常有香客問我,道長(zhǎng)脉漏,這世上最難降的妖魔是什么苞冯? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮侧巨,結(jié)果婚禮上舅锄,老公的妹妹穿的比我還像新娘。我一直安慰自己司忱,他們只是感情好皇忿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布畴蹭。 她就那樣靜靜地躺著,像睡著了一般鳍烁。 火紅的嫁衣襯著肌膚如雪叨襟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天老翘,我揣著相機(jī)與錄音芹啥,去河邊找鬼。 笑死铺峭,一個(gè)胖子當(dāng)著我的面吹牛墓怀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播卫键,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼傀履,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了莉炉?” 一聲冷哼從身側(cè)響起钓账,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎絮宁,沒想到半個(gè)月后梆暮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绍昂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年啦粹,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窘游。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡唠椭,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出忍饰,到底是詐尸還是另有隱情贪嫂,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布艾蓝,位于F島的核電站力崇,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏赢织。R本人自食惡果不足惜餐曹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望敌厘。 院中可真熱鬧台猴,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至休讳,卻和暖如春讲婚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背俊柔。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工筹麸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人雏婶。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓物赶,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親留晚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子酵紫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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