JS 筆記 | Event Loop

更新 發佈閱讀 3 分鐘

在講什麼是 Event loop 之前必須先記得 JavaScript 的運作方式是單執行緒 (single-threaded),也就是它一次只能做一件事情,所有的函式都得乖乖排隊等著被執行,這種事件又叫做同步 (synchronous)

在同步下,程式碼中的函式一多,或者複雜度提高,就增加了排隊等著被執行的時間,大概就有點像是大家在高速公路上排隊等著下交流道,然後就會很驚喜地發現:哇喔,網頁卡住了!這種塞住的現象被稱作阻塞 (blocking)。但是很明顯,做為開發網頁的第一大語言,JavaScript 一定會克服這種阻塞的現象來造就現在大家使用的這麼順暢的網頁 UI,於是非同步 (asynchronous) 就出現了!

非同步的出現可以讓 JavaScript 並發 (concurrency) 運作程式碼中的函式,讓單線程的執行變成多線程,因此避免了阻塞的發生。這樣的結果就是需要依賴今天的主角 Event loop 啦!

再來談談 Call stack, Web API, Callback queue。Call stack 會追蹤我們呼叫的函式,通常來說,在同步下就只會有Call stack 的存在,所以阻塞就是阻塞在 Call stack 這裡,可以把它想像成高速公路的交流道,一堆車子都擠在這裡等著下去。

JavaScript 的非同步,在 Call stack 中出現瀏覽器負責處理的函式 (如 setTimeout) 時,會從 Call stack 中將該函式取出丟到 Web API 的地方去執行,執行完畢再丟到 Callback queue 去,等著再被塞回 Call stack 中去輸出結果。

那 Event loop 呢?Event loop 哪裡去了?Event loop 所扮演的角色就是當 Call stack 中為空閒時,把 Callback queue 的回調函式 (callback) 丟回 Call stack 中。

這樣做的好處就是如setTimeout在 Web API 中執行時,其他不需要進入到 Web API 的程式碼,比如console.log直接可以在 Call stack 中執行而不用去乖乖等待setTimeout執行完畢,達到分流的效果。



舉個 Philip Roberts 在 JSConf EU 介紹 event loop 中的例子:

console.log(‘hi’);

setTimeout(function cb(){
console.log(‘there’);
}, 5000);

console.log(‘JSConfEU’)

產出的結果順序會是:

  1. hi
  2. JSConfEU
  3. there

按照前面講的非同步來解釋事情是怎麼發生的:

  1. console.log(‘hi’)塞入 Call stack,執行,移出 Call stack。
  2. setTimeout塞入 Call stack,在 Web API 啟動倒數計時,移出 Call stack 。
  3. console.log(‘JSConfEU’)塞入 Call stack,執行,移出 Call stack。
  4. Web API 繼續執行倒數計時。
  5. 倒數計時結束,cb塞入 Callback queue。
  6. console.log(‘there’)塞入 Call stack,執行,移出 Call stack。
來個圖解會更清楚~

來個圖解會更清楚~

那如果今天把setTimeout設定為0呢?會得到不一樣的順序嗎?答案是不會,輸出結果順序依然跟倒數5秒一樣,那是因為setTimeout這個函式必然是要進入 Web API, Callback queue 然後再回到 Call stack 跑上這麼一圈的。



推薦大家去看看 Philip Roberts 在 JSConf EU 的影片:


留言
avatar-img
留言分享你的想法!
avatar-img
Jeremy Ho的沙龍
20會員
37內容數
這個專題用來存放我在學習網頁開發時的心得及知識。
Jeremy Ho的沙龍的其他內容
2023/11/17
2023/11/17
2023/11/16
TypeScript 基礎語法
Thumbnail
2023/11/16
TypeScript 基礎語法
Thumbnail
2023/11/13
JavaScript callback, promise, async-await
Thumbnail
2023/11/13
JavaScript callback, promise, async-await
Thumbnail
看更多
你可能也想看
Thumbnail
透過蝦皮分潤計畫,輕鬆賺取零用金!本文分享5-6月實測心得,包含數據流程、實際收入、平臺優點及注意事項,並推薦高分潤商品,教你如何運用空閒時間創造被動收入。
Thumbnail
透過蝦皮分潤計畫,輕鬆賺取零用金!本文分享5-6月實測心得,包含數據流程、實際收入、平臺優點及注意事項,並推薦高分潤商品,教你如何運用空閒時間創造被動收入。
Thumbnail
單身的人有些會養寵物,而我養植物。畢竟寵物離世會傷心,植物沒養好再接再厲就好了~(笑)
Thumbnail
單身的人有些會養寵物,而我養植物。畢竟寵物離世會傷心,植物沒養好再接再厲就好了~(笑)
Thumbnail
不知你有沒有過這種經驗?衛生紙只剩最後一包、洗衣精倒不出來,或電池突然沒電。這次一次補貨,從電池、衛生紙到洗衣精,還順便分享使用心得。更棒的是,搭配蝦皮分潤計畫,愛用品不僅自己用得安心,分享給朋友還能賺回饋。立即使用推薦碼 X5Q344E,輕鬆上手,隨時隨地賺取分潤!
Thumbnail
不知你有沒有過這種經驗?衛生紙只剩最後一包、洗衣精倒不出來,或電池突然沒電。這次一次補貨,從電池、衛生紙到洗衣精,還順便分享使用心得。更棒的是,搭配蝦皮分潤計畫,愛用品不僅自己用得安心,分享給朋友還能賺回饋。立即使用推薦碼 X5Q344E,輕鬆上手,隨時隨地賺取分潤!
Thumbnail
身為一個典型的社畜,上班時間被會議、進度、KPI 塞得滿滿,下班後只想要找一個能夠安靜喘口氣的小角落。對我來說,畫畫就是那個屬於自己的小樹洞。無論是胡亂塗鴉,還是慢慢描繪喜歡的插畫人物,那個專注在筆觸和色彩的過程,就像在幫心靈按摩一樣,讓緊繃的神經慢慢鬆開。
Thumbnail
身為一個典型的社畜,上班時間被會議、進度、KPI 塞得滿滿,下班後只想要找一個能夠安靜喘口氣的小角落。對我來說,畫畫就是那個屬於自己的小樹洞。無論是胡亂塗鴉,還是慢慢描繪喜歡的插畫人物,那個專注在筆觸和色彩的過程,就像在幫心靈按摩一樣,讓緊繃的神經慢慢鬆開。
Thumbnail
簡要說明 JavaScript 的 Event Loop JavaScript 是單執行緒 (single-threaded) 語言,這意味著它一次只能執行一件事,因此所有函式都需要排隊等待執行,這被稱為同步 (synchronous)。在同步操作中,若函式過多或過於複雜,會導致程式阻塞 (blo
Thumbnail
簡要說明 JavaScript 的 Event Loop JavaScript 是單執行緒 (single-threaded) 語言,這意味著它一次只能執行一件事,因此所有函式都需要排隊等待執行,這被稱為同步 (synchronous)。在同步操作中,若函式過多或過於複雜,會導致程式阻塞 (blo
Thumbnail
歡迎來到 React 白話文運動第三篇,今天我們將深入探討 JavaScript 中的非同步操作,並介紹兩個重要的關鍵字:Async 與 Await。在這篇文章中,我們將透過實例演示非同步操作的概念,以及如何使用 Promise、Fetch、Async 和 Await 來更有效地處理非同步程式。
Thumbnail
歡迎來到 React 白話文運動第三篇,今天我們將深入探討 JavaScript 中的非同步操作,並介紹兩個重要的關鍵字:Async 與 Await。在這篇文章中,我們將透過實例演示非同步操作的概念,以及如何使用 Promise、Fetch、Async 和 Await 來更有效地處理非同步程式。
Thumbnail
記錄一下 API 串接的四種方式 www
Thumbnail
記錄一下 API 串接的四種方式 www
Thumbnail
Web Workers主要提供簡單的API讓網頁在背景執行緒中執行程式而不干擾使用者的操作。 javascript主要功能是與user操作頁面互動及操作dom,試想若使用多執行緒的概念,那麼一個動作是新增至某個dom節點,另一個動作則是修改該dom節點,此時瀏覽器應該使用哪個動作為準? 所以為了避免
Thumbnail
Web Workers主要提供簡單的API讓網頁在背景執行緒中執行程式而不干擾使用者的操作。 javascript主要功能是與user操作頁面互動及操作dom,試想若使用多執行緒的概念,那麼一個動作是新增至某個dom節點,另一個動作則是修改該dom節點,此時瀏覽器應該使用哪個動作為準? 所以為了避免
Thumbnail
執行以上程式碼,然後看到了這個結果: 為什麼「延遲0秒」的函式寫在上方,但在console印出的結果,它還是被排在第二順位? 利用AC教材提供的youtube演講連結一窺究竟: 演講提供了更多JS的細節概念,身為JS新手的我還在消化,但若針對教案提出的問題來回答,加上利用google大神查到MDN的
Thumbnail
執行以上程式碼,然後看到了這個結果: 為什麼「延遲0秒」的函式寫在上方,但在console印出的結果,它還是被排在第二順位? 利用AC教材提供的youtube演講連結一窺究竟: 演講提供了更多JS的細節概念,身為JS新手的我還在消化,但若針對教案提出的問題來回答,加上利用google大神查到MDN的
Thumbnail
介紹 委派的非同步方法 可以透過BeginInvoke執行委派的非同步方法 Action<T>.BeginInvoke(<T> obj,AsyncCallback callback,Object @object) 第一個內容的 obj,只的是要傳入acction委派的參數 第二個AsyncCallb
Thumbnail
介紹 委派的非同步方法 可以透過BeginInvoke執行委派的非同步方法 Action<T>.BeginInvoke(<T> obj,AsyncCallback callback,Object @object) 第一個內容的 obj,只的是要傳入acction委派的參數 第二個AsyncCallb
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News