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

JavaScript特點是”非阻塞“眼刃,V8引擎通過事件循環(huán)event loop來實現(xiàn)這一特點而咆。

1. 執(zhí)行棧與事件隊列

當javaScript代碼執(zhí)行的時候會將不同的變量存于內(nèi)存中的不同位置:堆heap 和棧stack中來加以區(qū)分。其中烟零, 堆里存放著一些對象瘪松。而棧中則存放這一些基礎型變量以及對象指針。

當調(diào)用一個方法時瓶摆, JS會生成一個與這個方法對應的執(zhí)行環(huán)境context,又叫執(zhí)行上下文凉逛。 這個執(zhí)行環(huán)境中有這個方法的私有作用域, 上層作用域的指向群井, 方法的參數(shù)状飞, 這個作用域中定義的變量以及這個作用域的this對象。 而依次調(diào)用的時候书斜, 因為JS是單線程的诬辈, 同一時間只能執(zhí)行一個方法, 于是這些方法被排隊在一個單獨的地方荐吉。 這個地方被稱為執(zhí)行棧焙糟。

當一個腳本第一次執(zhí)行的時候, JS引擎會解析這段代碼样屠, 并將其中的同步代碼按照執(zhí)行順序加入執(zhí)行棧中穿撮, 然后從頭開始執(zhí)行。如果當前執(zhí)行的是一個方法痪欲。 當這個執(zhí)行環(huán)境中的代碼執(zhí)行完畢并返回結(jié)果后悦穿, js會退出這個執(zhí)行環(huán)境并把這個執(zhí)行環(huán)境銷毀, 回到上一個方法的執(zhí)行環(huán)境业踢。 ......這個過程反復進行栗柒, 直到執(zhí)行棧中的代碼全部執(zhí)行完畢。

global初次運行腳本時向執(zhí)行棧中加入代碼:

上圖:一個方法執(zhí)行會向執(zhí)行棧中加入這個方法的執(zhí)行環(huán)境知举, 在這個執(zhí)行環(huán)境中還可以調(diào)用其他方法瞬沦, 甚至是自己太伊, 其結(jié)果不過是在執(zhí)行棧中再添加一個執(zhí)行環(huán)境。 這個過程可以是無限進行下去的逛钻,除非發(fā)生了棧溢出僚焦, 即超出了所能使用內(nèi)存的最大值。

\color{blue}{- 異步代碼執(zhí)行 ? }
當一個異步代碼(如發(fā)送ajax請求數(shù)據(jù))執(zhí)行后會如何呢绣的? 開頭說叠赐, js的一大特點是 非阻塞, 實現(xiàn)這一點的關鍵在于一項機制——事件隊列Task Queue

js引擎遇到一個異步事件后并不會一直等待其返回結(jié)果屡江, 而是會將這個事件掛起(pending)芭概, 繼續(xù)執(zhí)行執(zhí)行棧中的其他任務。 當一個異步事件返回結(jié)果后惩嘉, js會將這個事件加入與當前執(zhí)行棧不同的另一個隊列罢洲, 我們稱之為事件隊列。 被放入事件隊列的不會立刻執(zhí)行其回調(diào)文黎。 而是等待當前執(zhí)行棧中的所有任務都執(zhí)行完畢惹苗, 主線程處于閑置狀態(tài)時, 主線程會去查找事件隊列是否有任務耸峭。 如果有桩蓉, 那么主線程會取出排在第一位的事件, 并把這個事件對應的回調(diào)放入執(zhí)行棧中劳闹, 然后執(zhí)行其中的同步代碼......, 如此反復院究, 這樣就形成了一個無限循環(huán)。 這個過程被稱之為”事件循環(huán)Event Loop“本涕。

過程圖片如下:



stack :表示我們所說的執(zhí)行棧
web apis: 代表一些異步事件
callback queue: 事件隊列业汰。

2. macro task宏任務 和 micro task微任務

以上的事件循環(huán)過程是一個宏觀的表述, 實際上因為異步任務之間并不相同菩颖, 因此他們的執(zhí)行優(yōu)先級也有區(qū)別样漆。 不同的異步任務分為兩大類: 微任務 micro task 和 宏任務 macro task
以下事件屬于宏任務:

setInterval()
setTimeout()

以下事件屬于微任務:

new Promise()
new MutaionObserver()

前面介紹了晦闰,在一個事件循環(huán)中放祟, 異步事件返回結(jié)果后會被放到一個任務隊列中。 然而呻右,根據(jù)這個異步事件的類型舞竿, 這個事件實際上會劃分到對應的宏任務隊列和微任務隊列中去。 并且在當前執(zhí)行棧為空的時候窿冯, 主線程會查看微任務隊列中是否有事件存在。 如果存在确徙,則會依次執(zhí)行隊列中事件對應的回調(diào)醒串,直到微任務隊列為空执桌。 然后去宏任務隊列中取出最前面的一個事件, 把對應的回調(diào)加入當前執(zhí)行棧... 反復如此芜赌, 進入循環(huán)仰挣。

例子:

setTimeout(function() {
  console.log(1);
})

new Promise(function(resolve, reject) {
  console.log(2);
  resolve(3);
}).then(function(res) => {
  console.log(res);
})

結(jié)果為: 2 3 1

注意: 當 當前執(zhí)行棧執(zhí)行完畢時會優(yōu)先處理所有微任務任務隊列中的事件, 然后再去宏任務隊列中取出一個事件缠沈。 同一次事件循環(huán)中膘壶, 微任務永遠在宏任務之前執(zhí)行

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市洲愤,隨后出現(xiàn)的幾起案子颓芭,更是在濱河造成了極大的恐慌,老刑警劉巖柬赐,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件亡问,死亡現(xiàn)場離奇詭異,居然都是意外死亡肛宋,警方通過查閱死者的電腦和手機州藕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來酝陈,“玉大人床玻,你說我怎么就攤上這事〕涟铮” “怎么了锈死?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長遇西。 經(jīng)常有香客問我馅精,道長,這世上最難降的妖魔是什么粱檀? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任洲敢,我火速辦了婚禮,結(jié)果婚禮上茄蚯,老公的妹妹穿的比我還像新娘压彭。我一直安慰自己,他們只是感情好渗常,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布壮不。 她就那樣靜靜地躺著,像睡著了一般皱碘。 火紅的嫁衣襯著肌膚如雪询一。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天,我揣著相機與錄音健蕊,去河邊找鬼菱阵。 笑死,一個胖子當著我的面吹牛缩功,可吹牛的內(nèi)容都是我干的晴及。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嫡锌,長吁一口氣:“原來是場噩夢啊……” “哼虑稼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起势木,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蛛倦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后跟压,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胰蝠,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年震蒋,在試婚紗的時候發(fā)現(xiàn)自己被綠了茸塞。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡查剖,死狀恐怖钾虐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情笋庄,我是刑警寧澤效扫,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站直砂,受9級特大地震影響菌仁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜静暂,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一济丘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧洽蛀,春花似錦摹迷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至驮审,卻和暖如春鲫寄,著一層夾襖步出監(jiān)牢的瞬間吉执,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工塔拳, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鼠证,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓靠抑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親适掰。 傳聞我的和親對象是個殘疾皇子颂碧,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

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