夯基礎(chǔ)- js event loop機(jī)制

js運(yùn)行機(jī)制

event loop事件循環(huán)

  1. js分為同步任務(wù)和異步任務(wù)潦蝇,所有的同步任務(wù)都在主線程上執(zhí)行
  2. 另外存在著一個(gè)“任務(wù)隊(duì)列”涉枫,只要異步的任務(wù)有了結(jié)果梧田,便在任務(wù)隊(duì)列里面加入一個(gè)事件
  3. 當(dāng)主線程的的同步任務(wù)都執(zhí)行完了萌业,執(zhí)行棧清空,這個(gè)時(shí)候會去讀取任務(wù)隊(duì)列乡范,依次把他們?nèi)拥街骶€程執(zhí)行
  4. 這個(gè)過程不斷循環(huán)配名,就成了js的事件循環(huán)機(jī)制。

所以我們不難理解有的時(shí)候setTimeout(fn, 0)沒有立即執(zhí)行晋辆,它只是被立即加入到任務(wù)隊(duì)列了渠脉,可能那個(gè)時(shí)候主線程還沒有執(zhí)行完畢,所以它要等著瓶佳,等js引擎空閑的時(shí)候再執(zhí)行芋膘。

任務(wù)隊(duì)列是由js的事件觸發(fā)線程控制,不是js引擎所控制霸饲,可能js引擎太忙了为朋,瀏覽器又單獨(dú)開了一個(gè)線程

宏任務(wù)(macrotask) 、微任務(wù)(microtask)

如果我們遇到諸如類似的,那么誰先執(zhí)行呢厚脉,這就引出了宏任務(wù)习寸,微任務(wù)的概念。

console.log(1)

Promise.resolve().then(() => {
    console.log('promise')
})

setTimeout(() => {
    console.log('settimeout')  
})
宏任務(wù)

每次執(zhí)行棧執(zhí)行的代碼就是一個(gè)宏任務(wù)傻工,包括把任務(wù)隊(duì)列的事件加入到主線程的執(zhí)行霞溪,一個(gè)宏任務(wù)的執(zhí)行相當(dāng)于一個(gè)task孵滞,瀏覽器會在一個(gè)task結(jié)束之后對頁面進(jìn)行重新渲染。

常見的macrotask:setTimeout鸯匹、setInterval坊饶、setImmediate、I/O等

微任務(wù)

microtask又是個(gè)什么東東殴蓬?在一個(gè)task執(zhí)行之后緊跟著執(zhí)行的東西匿级,也就是一個(gè)task執(zhí)行完畢,接下來會把它在執(zhí)行期間產(chǎn)生等所有微任務(wù)都進(jìn)行執(zhí)行科雳,也就是要把微任務(wù)隊(duì)列執(zhí)行清空掉根蟹,接下來瀏覽器開始對頁面進(jìn)行重新渲染。

常見的microtask:Promise.then糟秘、process.nextTick、MutaionObserver

image

小結(jié)

結(jié)合上宏任務(wù)球散、微任務(wù)再來總結(jié)一下js的事件循環(huán)機(jī)制尿赚。

  1. 執(zhí)行同步代碼,也就是開始一個(gè)宏任務(wù)的執(zhí)行
  2. 如果遇到異步蕉堰,等異步任務(wù)有了運(yùn)行結(jié)果后再把他們放到事件隊(duì)列凌净,如果屬于微任務(wù)的話加入微任務(wù)隊(duì)列。
  3. 宏任務(wù)執(zhí)行完畢屋讶,接下來把這個(gè)task執(zhí)行過程中產(chǎn)生的微任務(wù)依次執(zhí)行
  4. 微任務(wù)全部執(zhí)行完畢冰寻,瀏覽器開始重新渲染
  5. 去事件隊(duì)列讀取下一個(gè)宏任務(wù),不斷循環(huán)上面過程皿渗。
// 舉個(gè)栗子??

console.log('1');

setTimeout(function() {
    console.log('2');
    Promise.resolve().then(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
}, 100)

Promise.resolve().then(function() {
    console.log('6');
})

new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
   Promise.resolve().then(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})

console.log('13')

第一次事件循環(huán)斩芭,首先打印了1,然后遇到setTimeout乐疆,我們記為setA划乖,setA去外面排隊(duì),接下來Promise.then屬于微任務(wù)挤土,加入微任務(wù)隊(duì)列琴庵。再往下遇到new Promise,直接執(zhí)行打印7仰美,then函數(shù)加入微任務(wù)隊(duì)列迷殿。再繼續(xù)又遇到setTimeout,我們記為setB咖杂,排隊(duì)等著庆寺。然后打印13。所以第一輪事件循環(huán)結(jié)束翰苫,我們直接打印了1止邮,7这橙,13,緊接著依次打印微任務(wù)隊(duì)列里面的6导披,8屈扎。

現(xiàn)在第一輪事件循環(huán)結(jié)束,還有setA,setB等待執(zhí)行撩匕,先執(zhí)行哪個(gè)呢鹰晨?答案是setB。雖然定時(shí)器線程先捕捉到了setA止毕,但是setA延遲時(shí)間是100ms模蜡,而setB是立即執(zhí)行的,setB會在setA之前被加入到事件隊(duì)列扁凛。所以當(dāng)?shù)谝惠喪录h(huán)結(jié)束忍疾,此時(shí)會把setB從事件隊(duì)列拉到執(zhí)行棧中執(zhí)行,第二輪事件循環(huán)開始了谨朝。

第二次循環(huán)首先打印了9卤妒,然后遇到微任務(wù),把10加入到微任務(wù)隊(duì)列字币,往下又遇到了new Promise直接執(zhí)行则披,打印11,then函數(shù)的12被加入到微任務(wù)洗出,本次事件循環(huán)結(jié)束士复。依次打印了9,11翩活,10阱洪,12.

第三輪事件循環(huán)開始,setA所在的宏任務(wù)隅茎,首先打印了2澄峰,然后3被加入到微任務(wù),同樣的辟犀,打印4俏竞,then函數(shù)的5被加入到微任務(wù)隊(duì)列。本輪事件循環(huán)結(jié)束堂竟,依次打印2魂毁,4,3出嘹,5.

最終結(jié)果:1席楚,7,13税稼,6烦秩,8垮斯,9,11只祠,10兜蠕,12,2抛寝,4熊杨,3,5

參考資料:https://dailc.github.io

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末盗舰,一起剝皮案震驚了整個(gè)濱河市晶府,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌钻趋,老刑警劉巖川陆,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蛮位,居然都是意外死亡书劝,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門土至,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人猾昆,你說我怎么就攤上這事陶因。” “怎么了垂蜗?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵楷扬,是天一觀的道長。 經(jīng)常有香客問我贴见,道長烘苹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任片部,我火速辦了婚禮镣衡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘档悠。我一直安慰自己廊鸥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布辖所。 她就那樣靜靜地躺著惰说,像睡著了一般。 火紅的嫁衣襯著肌膚如雪缘回。 梳的紋絲不亂的頭發(fā)上吆视,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天典挑,我揣著相機(jī)與錄音,去河邊找鬼啦吧。 笑死您觉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丰滑。 我是一名探鬼主播顾犹,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼褒墨!你這毒婦竟也來了炫刷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤郁妈,失蹤者是張志新(化名)和其女友劉穎浑玛,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體噩咪,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡顾彰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了胃碾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涨享。...
    茶點(diǎn)故事閱讀 38,716評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖仆百,靈堂內(nèi)的尸體忽然破棺而出厕隧,到底是詐尸還是另有隱情,我是刑警寧澤俄周,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布吁讨,位于F島的核電站,受9級特大地震影響峦朗,放射性物質(zhì)發(fā)生泄漏建丧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一波势、第九天 我趴在偏房一處隱蔽的房頂上張望翎朱。 院中可真熱鬧,春花似錦艰亮、人聲如沸闭翩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疗韵。三九已至,卻和暖如春侄非,著一層夾襖步出監(jiān)牢的瞬間蕉汪,已是汗流浹背流译。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留者疤,地道東北人福澡。 一個(gè)月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像驹马,于是被迫代替她去往敵國和親革砸。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評論 2 350