理解 JavaScript 事件循環(huán)機制

前言

瀏覽器執(zhí)行環(huán)境的核心思想基于:同一時刻只能執(zhí)行一個代碼片 段跷敬,即所謂的單線程執(zhí)行模型麻车。想象一下在銀行柜臺前排隊,每個人進 入一支隊伍等待叫號并“處理”受裹。但JavaScript則只開啟了一個營業(yè)柜臺碌补! 每當輪到某個顧客時(某個事件),只能處理該位顧客棉饶。

來看下面這段 JavaScript 代碼:

console.log('script start');

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

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

console.log('script end');

先猜測一下這段代碼的輸出順序是什么?

事件循環(huán)和任務隊列

所有的任務可以分為同步任務和異步任務厦章, 分別進入不同的執(zhí)行環(huán)境。
同步任務照藻,一般會直接進入到主線程中袜啃,立即執(zhí)行;而異步任務幸缕,就是異步執(zhí)行的任務(比如ajax網絡請求群发,setTimeout 定時函數等都屬于異步任務,異步任務會通過任務隊列( Event Queue )的機制來進行協(xié)調发乔。

當主線程內的任務執(zhí)行完畢熟妓,會去 任務隊列(Event Queue) 讀取對應的任務,推入主線程執(zhí)行栏尚。 上述過程的不斷重復就是我們說的 事件循環(huán)(Event Loop)起愈。

事件循環(huán)(Event Loop)通常至少需要兩個任務隊列:宏任務隊列和微任務隊列。兩種隊列在同一時 刻都只執(zhí)行一個任務译仗。


p1.png

代碼分析

如上所說抬虽, 讓我們來看看上段代碼的執(zhí)行過程:
1.整體 script 作為第一個宏任務進入主線程,遇到 console.log纵菌,輸出 script start
2.遇到 setTimeout阐污,其回調函數被分發(fā)到宏任務 Event Queue 中
3.遇到 Promise,其 then函數被分到到微任務 Event Queue 中,記為 then1咱圆,之后又遇到了 then 函數笛辟,將其分到微任務 Event Queue 中功氨,記為 then2
4.遇到 console.log,輸出 script end

至此隘膘,Event Queue 中存在三個任務:


p2.png

1.執(zhí)行微任務:執(zhí)行then1,輸出 promise1,
2.執(zhí)行微任務:執(zhí)行 then2杠览,輸出 promise2弯菊,
這樣就清空了所有微任務
3.執(zhí)行宏任務: 輸出 setTimeout
至此,輸出的順序是:
script start, script end, promise1, promise2, setTimeout

附上一題踱阿,你可以根據上述方法來做個練習:

console.log('script start');

setTimeout(function() {
  console.log('timeout1');
}, 10);

new Promise(resolve => {
    console.log('promise1');
    resolve();
    setTimeout(() => console.log('timeout2'), 10);
}).then(function() {
    console.log('then1')
})

console.log('script end');

總結

記住管钳,JavaScript 是一門單線程語言,異步操作都是放到事件循環(huán)隊列里面软舌,等待主執(zhí)行棧來執(zhí)行的才漆。

參考文獻

Tasks, microtasks, queues and schedules
JavaScript忍者秘籍第二版 第十三章 彌久歷新的事件

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市佛点,隨后出現(xiàn)的幾起案子醇滥,更是在濱河造成了極大的恐慌,老刑警劉巖超营,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸳玩,死亡現(xiàn)場離奇詭異,居然都是意外死亡演闭,警方通過查閱死者的電腦和手機不跟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來米碰,“玉大人窝革,你說我怎么就攤上這事÷雷” “怎么了虐译?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵,是天一觀的道長吴趴。 經常有香客問我菱蔬,道長,這世上最難降的妖魔是什么史侣? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任拴泌,我火速辦了婚禮,結果婚禮上惊橱,老公的妹妹穿的比我還像新娘蚪腐。我一直安慰自己,他們只是感情好税朴,可當我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布回季。 她就那樣靜靜地躺著家制,像睡著了一般。 火紅的嫁衣襯著肌膚如雪泡一。 梳的紋絲不亂的頭發(fā)上颤殴,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天,我揣著相機與錄音鼻忠,去河邊找鬼涵但。 笑死,一個胖子當著我的面吹牛帖蔓,可吹牛的內容都是我干的矮瘟。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼塑娇,長吁一口氣:“原來是場噩夢啊……” “哼澈侠!你這毒婦竟也來了?” 一聲冷哼從身側響起埋酬,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤哨啃,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后写妥,有當地人在樹林里發(fā)現(xiàn)了一具尸體棘催,經...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年耳标,在試婚紗的時候發(fā)現(xiàn)自己被綠了醇坝。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡次坡,死狀恐怖呼猪,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情砸琅,我是刑警寧澤宋距,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站症脂,受9級特大地震影響谚赎,放射性物質發(fā)生泄漏。R本人自食惡果不足惜诱篷,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一壶唤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧棕所,春花似錦闸盔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽躲撰。三九已至,卻和暖如春击费,著一層夾襖步出監(jiān)牢的瞬間拢蛋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工蔫巩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谆棱,地道東北人。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓批幌,卻偏偏與公主長得像础锐,于是被迫代替她去往敵國和親嗓节。 傳聞我的和親對象是個殘疾皇子荧缘,可洞房花燭夜當晚...
    茶點故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內容