回顧JavaScript的執(zhí)行機制

JavaScript代碼是一行一行按順序執(zhí)行的坏晦?
是萝玷,不是?

準確的說同步的代碼確實是按順序執(zhí)行的昆婿,然鵝異步代碼又是怎么執(zhí)行的球碉,那么我們今天重點討論的話題就是JS的異步任務是如何執(zhí)行的?

事件循環(huán)

了解JS的小伙伴都知道JS是單線程的仓蛆,可是我們經(jīng)常會聽到異步執(zhí)行任務睁冬,那么只有一個線程的JS是怎么來實現(xiàn)異步任務呢,想象一下只有一個主線程的工作模式看疙,如果有一個需要花費很長時間的任務占據(jù)著主線程豆拨,那么后面的任務都需要等待,這將給用戶帶來很差的體驗狼荞,所以JS把耗時的任務交給另外一個線程來處理(JS執(zhí)行的宿主環(huán)境:如瀏覽器會創(chuàng)建一個專門處理異步任務的線程辽装,以下簡稱瀏覽器)。瀏覽器的該線程會維護一個事件隊列相味,等瀏覽器執(zhí)行完任務后拾积,會把注冊的回調函數(shù)推入事件隊列中,當JS的主線程中的執(zhí)行棧為空丰涉,便會去讀取事件隊列中的回調函數(shù)拓巧,進入主線程執(zhí)行,上述過程會不斷的重復一死,也就是事件循環(huán),通過這樣的工作機制才能使得異步任務很好的完成肛度,

事件循環(huán).png

圖上所描述的任務執(zhí)行流程可以通過下面的代碼加深理解

console.log(1);
setTimeout(function(){console.log(2);}, 0); 
console.log(3);

上面這段代碼的執(zhí)行流程:

  • 全局執(zhí)行環(huán)境入棧,console入棧投慈,打印1承耿,出棧,
  • 遇到setTimeout交給宿主環(huán)境線程執(zhí)行伪煤,注冊回調函數(shù)
  • 繼續(xù)執(zhí)行console加袋,接著出棧,
  • setTimeout執(zhí)行完后抱既,回調函數(shù)進入event queue职烧,
    *此時, 執(zhí)行棧空閑后蚀之,主線程從Event Queue中讀取回調函數(shù)并執(zhí)行

異步任務的類型

如果我們對異步任務進行更精細的區(qū)分蝗敢,可以分為以下兩種且不同類型的任務也存在優(yōu)先級:

  • macro-task(宏任務):主代碼塊 > setTimeout/setInterval
  • micro-task(微任務):process.nextTick > Promise > async await

不同類型的異步任務會進入不同的事件隊列

事件循環(huán)是從宏任務開始,執(zhí)行完后足删,看是否有可執(zhí)行的微任務寿谴,如果有則執(zhí)行,執(zhí)行完又開始新的宏任務壹堰;無則執(zhí)行新的宏任務拭卿。

console.log('start');
setTimeout(function() {
    console.log('setTimeout');
    process.nextTick(function() {
    console.log('node');
  })
})

async function asyncFun1(){
  console.log('asyncFun1');
  await asyncFun2();
  console.log('asyncFun1 callback');
}

async function asyncFun2(){
  console.log('asyncFun2');
}

asyncFun1();

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

console.log('end');

//執(zhí)行結果:start—>asyncFun1—>asyncFun2—>promise—>end—>then—>asyncFun1 callback—>setTimeout—>node

第一次循環(huán):

  • 整體代碼塊被作為第一個宏任務進行主線程骡湖,遇到第一行的console贱纠,輸出start
  • 遇到setTimeout,回調函數(shù)被放在宏任務Event Queue中响蕴,記為setTimeout1
  • 遇到asyncFun1函數(shù)谆焊,執(zhí)行輸出asyncFun1,再遇到asyncFun2函數(shù)浦夷,輸出asyncFun2辖试,然后把該函數(shù)的回調放入微任務Event Queue中,記為async1
  • 遇到new promise直接執(zhí)行劈狐,輸出promise罐孝,then被放入微任務Event Queue,記為then

當?shù)谝淮问录h(huán)宏任務完成時肥缔,我們發(fā)現(xiàn)還有兩個微任務莲兢,分別執(zhí)行這兩個任務輸出:then ,asyncFun1 callback(微任務執(zhí)行的優(yōu)先級前面有提到

宏任務 微任務
setTimeout1 async1
then

到現(xiàn)在為止一次完整的事件循環(huán)才算結束了,輸出了start—>asyncFun1—>asyncFun2—>promise—>end—>then—>asyncFun1 callback

第二次循環(huán):

  • 接著從setTimeout宏任務入手续膳,打印setTimeout
  • 遇到process改艇,把函數(shù)放入微任務Event Loop中,記為process

第二次事件循環(huán)宏任務結束坟岔,還有一個微任務谒兄,執(zhí)行輸出node,第二次事件循環(huán)輸出:setTimeout—>node

宏任務 微任務
process

整段代碼的共執(zhí)行了兩次事件循環(huán)社付,完整輸出為:start—>asyncFun1—>asyncFun2—>promise—>end—>then—>asyncFun1 callback—>setTimeout—>node

以上是我對JS異步任務執(zhí)行的理解承疲,如后續(xù)有新的理解和認識,會加以補充~~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末鸥咖,一起剝皮案震驚了整個濱河市燕鸽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌扛或,老刑警劉巖绵咱,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡悲伶,警方通過查閱死者的電腦和手機艾恼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來麸锉,“玉大人钠绍,你說我怎么就攤上這事』ǔ粒” “怎么了柳爽?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長碱屁。 經(jīng)常有香客問我磷脯,道長,這世上最難降的妖魔是什么娩脾? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任赵誓,我火速辦了婚禮,結果婚禮上柿赊,老公的妹妹穿的比我還像新娘俩功。我一直安慰自己,他們只是感情好碰声,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布诡蜓。 她就那樣靜靜地躺著,像睡著了一般胰挑。 火紅的嫁衣襯著肌膚如雪蔓罚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天洽腺,我揣著相機與錄音脚粟,去河邊找鬼。 笑死蘸朋,一個胖子當著我的面吹牛核无,可吹牛的內容都是我干的。 我是一名探鬼主播藕坯,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼团南,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了炼彪?” 一聲冷哼從身側響起吐根,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎辐马,沒想到半個月后拷橘,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年冗疮,在試婚紗的時候發(fā)現(xiàn)自己被綠了萄唇。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡术幔,死狀恐怖另萤,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情诅挑,我是刑警寧澤四敞,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站拔妥,受9級特大地震影響忿危,放射性物質發(fā)生泄漏。R本人自食惡果不足惜毒嫡,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一癌蚁、第九天 我趴在偏房一處隱蔽的房頂上張望幻梯。 院中可真熱鬧兜畸,春花似錦、人聲如沸碘梢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽煞躬。三九已至肛鹏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間恩沛,已是汗流浹背在扰。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留雷客,地道東北人芒珠。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像搅裙,于是被迫代替她去往敵國和親皱卓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355