JavaScript 的事件循環(huán)

不妨大膽一點斋攀,反正沒有誰能活著離開這世界

下載.jpg

在前端的面試中,常常會考察async 梧田,await淳蔼,setTimeout,Promise函數(shù)執(zhí)行的順序裁眯。請各位看官鹉梨,細聽分說。以后不再迷茫

任務隊列

  • JS分為同步任務和異步任務
  • 同步任務都在主線程上(其實js是單線程)執(zhí)行穿稳,由上至下形成一個執(zhí)行棧
  • 主線程之外存皂,事件觸發(fā)線程管理著一個任務隊列,來了異步任務有了運行結(jié)果逢艘,就在任務隊列里放置一個事件
  • 一旦執(zhí)行棧里所有的同步任務執(zhí)行完畢的時候(及時JS引擎空閑)旦袋,系統(tǒng)就會讀取任務隊列骤菠,將可運行的異步任務添加到可執(zhí)行棧中,依次開始執(zhí)行
image.png

宏任務

macrotask疤孕,可以理解為每次執(zhí)行棧執(zhí)行的代碼就是一個宏任務娩怎。瀏覽器為了能夠使得JS內(nèi)部macrotask與DOM任務能夠有序的執(zhí)行,會在一個macrotask執(zhí)行結(jié)束后胰柑,在一個macrotask執(zhí)行開始前截亦,對頁面進行重新渲染

(macro)task->渲染->(macro)task->...

macrotask主要包含:script(整體代碼)、setTimeout柬讨、setInterval崩瓤、I/O、UI交互事件踩官、postMessage却桶、MessageChannel、setImmediate(Node.js 環(huán)境)

微任務

microtask蔗牡,可以理解是在當前task執(zhí)行結(jié)束后立即執(zhí)行的任務颖系。也就是說在當前任務之后,下一個任務之前辩越,重新渲染之前嘁扼。
所以microtask的響應速度比setTimeout(setTimeout是任務)更快,在某一個macrotask執(zhí)行完后黔攒,就會將在它執(zhí)行期間產(chǎn)生的所有microtask都執(zhí)行完畢(在渲染之前)
microtask主要包含:Promise.then趁啸、MutaionObserver、process.nextTick(Node.js 環(huán)境)

運行機制

事件循環(huán)中督惰,每進行一次循環(huán)操作稱為tick

  • 執(zhí)行一個宏任務(執(zhí)行棧中沒有就從事件隊列中獲炔桓怠)
  • 執(zhí)行過程中如果遇到微服務,就將它添加到微服務的隊列
  • 宏任務執(zhí)行完畢后赏胚,立即執(zhí)行當前微服務隊列中的所有微服務(依次執(zhí)行)
  • 渲染完畢之后,JS線程繼續(xù)接管访娶,開始下一個宏任務


    image.png

Promise和async中的立即執(zhí)行

我們知道Promise中的異步體現(xiàn)在then和catch中,所以卸載Promise中的代碼是被當做同步任務立即執(zhí)行的觉阅。而在async/await中崖疤,在出現(xiàn)await之前,其中的代碼也是立即執(zhí)行的

await干了什么見不得人的事呢

await等待的是一個表達式留拾,這個表達式的返回值可以是一個promise對象也可以是其他值戳晌。由于因為async await 本身就是promise+generator的語法糖。所以await后面的代碼是microtask

做對下面的題痴柔,你就出師了

async function async1() {
    console.log('async1 start');
    await async2();
    console.log('async1 end');
}
async function async2() {
    console.log('async2');
}

console.log('script start');

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

async1();

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

分析:
首先打印script start沦偎,然后遇到了宏任務setTimeout,宏任務會加入到宏任務的隊列

image.png

這時候開始執(zhí)行async1(),async1中await之間立即執(zhí)行豪嚎,打印async1 start搔驼,然后輸出async2,await之后的加入微觀任務


image.png

然后遇到promise侈询,promise里面的立即執(zhí)行舌涨。then分配到微觀任務


image.png

最后打印script end
這時候開始清空微任務'async1 end',promise2
最最后在循環(huán)執(zhí)行宏任務扔字,只剩下setTimeout囊嘉,打印setTimeout

答案如下:

script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout

參考自:https://github.com/advanced-frontend/daily-interview-question/issues/7

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市革为,隨后出現(xiàn)的幾起案子扭粱,更是在濱河造成了極大的恐慌,老刑警劉巖震檩,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件琢蛤,死亡現(xiàn)場離奇詭異,居然都是意外死亡抛虏,警方通過查閱死者的電腦和手機博其,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來迂猴,“玉大人慕淡,你說我怎么就攤上這事〈沓溃” “怎么了儡率?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長以清。 經(jīng)常有香客問我,道長崎逃,這世上最難降的妖魔是什么掷倔? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮个绍,結(jié)果婚禮上勒葱,老公的妹妹穿的比我還像新娘。我一直安慰自己巴柿,他們只是感情好凛虽,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著广恢,像睡著了一般凯旋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天至非,我揣著相機與錄音钠署,去河邊找鬼。 笑死荒椭,一個胖子當著我的面吹牛谐鼎,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播趣惠,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼狸棍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了味悄?” 一聲冷哼從身側(cè)響起隔缀,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎傍菇,沒想到半個月后猾瘸,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡丢习,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年牵触,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咐低。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡揽思,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出见擦,到底是詐尸還是另有隱情钉汗,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布鲤屡,位于F島的核電站损痰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏酒来。R本人自食惡果不足惜卢未,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望堰汉。 院中可真熱鬧辽社,春花似錦、人聲如沸翘鸭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽就乓。三九已至汉匙,卻和暖如春拱烁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背盹兢。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工邻梆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人绎秒。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓浦妄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親见芹。 傳聞我的和親對象是個殘疾皇子剂娄,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

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