JS的Event-Loop

javascript中的Event-Loop

在之前的一篇文章中我們解釋了一下為什么JavaScript要設(shè)計(jì)成單線程以及這門(mén)語(yǔ)言的任務(wù)隊(duì)列的概念,這也幫助了我們簡(jiǎn)單了解了這門(mén)語(yǔ)言的運(yùn)行機(jī)制,那么今天我們就談?wù)勅蝿?wù)隊(duì)列相關(guān)的概念英古!

事件和回調(diào)函數(shù)

任務(wù)隊(duì)列其實(shí)是事件的一個(gè)隊(duì)列绊寻,也可以理解為消息隊(duì)列,當(dāng)IO設(shè)備完成一個(gè)任務(wù)的時(shí)候喘蟆,就會(huì)在任務(wù)隊(duì)列中添加一個(gè)事件季惯,用來(lái)表示當(dāng)前任務(wù)已經(jīng)執(zhí)行完了咬最,可以進(jìn)入執(zhí)行棧(也就是之前講過(guò)的主線程隊(duì)列)了翎嫡,主線程讀取任務(wù)隊(duì)列也就是讀取有哪些事件!

任務(wù)隊(duì)列中的事件除了IO設(shè)備之外永乌,還有用戶點(diǎn)擊惑申、鍵盤(pán)事件等,只要指定過(guò)回調(diào)函數(shù)翅雏,這些事件發(fā)生時(shí)就會(huì)進(jìn)入任務(wù)隊(duì)列圈驼,然后等待主線程讀取望几。

回調(diào)函數(shù)(callback)其實(shí)就是被主線程掛起來(lái)的代碼绩脆,主線程執(zhí)行異步任務(wù),其實(shí)就是執(zhí)行回調(diào)函數(shù)橄抹!

任務(wù)隊(duì)列其實(shí)是一個(gè)先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)靴迫,也就是說(shuō)排在前面的事件會(huì)被優(yōu)先讀取,當(dāng)主線程的代碼執(zhí)行完楼誓,執(zhí)行棧被清空以后玉锌,就會(huì)立即執(zhí)行任務(wù)隊(duì)列中排在最前面的事件,但是由于定時(shí)器的功能疟羹,因此主守,主線程需要檢查一下執(zhí)行時(shí)間,某些事件只有等到規(guī)定的時(shí)間榄融,才可以返回主線程参淫!

Event Loop

主線程從任務(wù)隊(duì)列讀取事件這個(gè)過(guò)程是循環(huán)不斷的,因此整個(gè)過(guò)程又被稱為Event Loop(事件循環(huán))

setTimeout(() => {
  console.log('timeout1');
}, 0)
console.log(1);
setTimeout(() => {
  console.log('timeout2');
}, 0)
console.log(2);
// 1 2 timeout1 timeout2

上面代碼中有兩個(gè)定時(shí)器愧杯,定時(shí)器也會(huì)放在任務(wù)隊(duì)列中涎才,因此我們常說(shuō)在js中定時(shí)器可以模擬異步,其實(shí)是js默認(rèn)會(huì)把定時(shí)器放在任務(wù)隊(duì)列民效,前面我們講過(guò)憔维,js先會(huì)執(zhí)行主線程的代碼涛救,稱為執(zhí)行棧,當(dāng)執(zhí)行棧的代碼執(zhí)行結(jié)束业扒,執(zhí)行棧清空之后才會(huì)執(zhí)行任務(wù)隊(duì)列中的代碼, 因此上面的代碼不會(huì)因?yàn)槎〞r(shí)器在前面检吆,而先執(zhí)行定時(shí)器,當(dāng)定時(shí)器的間隔時(shí)間一致時(shí)程储,按照添加順序蹭沛,先進(jìn)任務(wù)隊(duì)列則先執(zhí)行!

NodeJs的Event Loop

NodeJs也是單線程的Event Loop章鲤,但是它區(qū)別于瀏覽器的運(yùn)行環(huán)境摊灭;
在Nodejs中提供了process.nextTice()和setImmediate()兩個(gè)與任務(wù)隊(duì)列有關(guān)的方法;

process.nextTice()就是在當(dāng)前執(zhí)行棧尾部添加任務(wù)败徊,也就是任務(wù)隊(duì)列(所有的異步任務(wù))開(kāi)始之前帚呼;

console.log(1);
setTimeout(function timeout() {
  console.log('timeout1');
}, 0);

process.nextTick(function() {
  console.log(3);
  process.nextTick(function(){
    console.log(4);
  });
});

setTimeout(function timeout() {
  console.log('timeout2');
}, 0);

console.log(2);

// 1 2 3 4 timeout1 timeout2

setImmediate()會(huì)在每一次Event Loop結(jié)束執(zhí)行霞怀,或者說(shuō)下一次Event Loop執(zhí)行之前執(zhí)行

console.log('start');
setTimeout(function() {
    console.log('timeout1');
}, 0);
setImmediate(function (){
    setImmediate(function() {
        console.log(1);
        setTimeout(function() {
            console.log('timeout3');
        }, 0);
        setImmediate(function(){
            console.log(2);
        });
    });
    setTimeout(function() {
        console.log('timeout2');
    }, 0);
});
process.nextTick(function() {
    console.log('nextTick1');
    process.nextTick(function() {
        console.log('nextTick2')
    })
})
console.log('end');
// start end nextTick1 nextTick2 timeout1 1 timeout2 2 timeout3

上面代碼前三個(gè)輸出結(jié)果在沒(méi)有其他干擾拌汇,就目前代碼欺冀,不用質(zhì)疑锦溪,主線程肯定先執(zhí)行坪稽,接下來(lái)為nextTick阿迈,因?yàn)樗鼤?huì)被放在所有異步執(zhí)行之前毡代,不論是否嵌套(不包括嵌套在其他異步函數(shù)中)笤喳,timeout1在主線程程中被添加到任務(wù)隊(duì)列辜妓,不論它是否在start之后還是end之前枯途,它是區(qū)別于其他函數(shù)的唯一一個(gè)在任務(wù)隊(duì)列頂端的函數(shù),而setImmediate總會(huì)在一個(gè)Event Loop之后執(zhí)行籍滴!

下篇我們我們聊聊任務(wù)隊(duì)列中的微任務(wù)和宏任務(wù)酪夷!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市异逐,隨后出現(xiàn)的幾起案子捶索,更是在濱河造成了極大的恐慌,老刑警劉巖灰瞻,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腥例,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡酝润,警方通過(guò)查閱死者的電腦和手機(jī)燎竖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)要销,“玉大人构回,你說(shuō)我怎么就攤上這事。” “怎么了纤掸?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵脐供,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我借跪,道長(zhǎng)政己,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任掏愁,我火速辦了婚禮歇由,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘果港。我一直安慰自己沦泌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布辛掠。 她就那樣靜靜地躺著谢谦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪公浪。 梳的紋絲不亂的頭發(fā)上他宛,一...
    開(kāi)封第一講書(shū)人閱讀 52,158評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音欠气,去河邊找鬼。 笑死镜撩,一個(gè)胖子當(dāng)著我的面吹牛预柒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播袁梗,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼宜鸯,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了遮怜?” 一聲冷哼從身側(cè)響起淋袖,我...
    開(kāi)封第一講書(shū)人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎锯梁,沒(méi)想到半個(gè)月后即碗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡陌凳,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年剥懒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片合敦。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡初橘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情保檐,我是刑警寧澤耕蝉,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站夜只,受9級(jí)特大地震影響赔硫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜盐肃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一爪膊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧砸王,春花似錦推盛、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至驹闰,卻和暖如春瘪菌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嘹朗。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工师妙, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人屹培。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓默穴,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親褪秀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蓄诽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

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