iT邦幫忙

2023 iThome 鐵人賽

DAY 9
1
自我挑戰組

複習 JavaScript 核心概念系列 第 9

[Day 09] 不可不知的事件循環(Event Loop)

  • 分享至 

  • xImage
  •  

昨天稍微講了 同步非同步 ,而實際上 JavaScript 是怎麼做到非同步的,那就是今天的主體:事件循環(Event Loop)。在這之前,要先來介紹整個瀏覽器環境中除了 JavaScript 本身外的兩大組成要素,分別是 Web APIsCallback Queue(回調佇列)

Web APIs

我們在使用 JavaScript 的非同步程式碼時,其實是依靠一個稱為Web APIs的酷東西,它是瀏覽器提供的一系列非同步操作Api,用於處理網絡請求、計時器、DOM 操作等。當使用 Web APIs(例如 setTimeout、fetch、XMLHttpRequest 等)執行非同步操作時,這些操作會在背景中運行,而不會阻塞 JavaScript 的執行;而當操作完成後,會將對應的 callback function(回調函式) 放入 Callback Queue

Callback Queue(回調佇列中的)

Callback Queue,或稱Task Queue,是一個先進先出(FIFO,先進先出)的資料結構,這裡存放來自 Web APIs 完成非同步操作後回傳的callback(回調函式)

這些放在佇列中的callback會一直等待,直到適當的時機點被移出佇列。
這個時機點為 JavaScript 的的呼叫堆疊(call stack)為空的時候(即當所有同步操作完成後),Callback Queuecallback 會一個一個依序被移出佇列並放入JavaScript的呼叫堆疊(call stack)中執行。


只看文字或許不太明白,我們直接來看圖。 (圖片來源

上圖是整個瀏覽器環境中整體的運作流程,可以明顯看到三大區塊:JS引擎Web APIsCallback Queue
先簡單分析上圖,先看左上,JavaScript 堆疊(Call Stack)最頂端的 setTimeout() 是非同步,因此它會被交給 WebApis 去處理,而 JS引擎 則會繼續執行 showText() ,就這樣一直執行堆疊中剩下的內容。

而另一邊當 WebApis 將 setTimeout() 處理完畢時,它會將「setTimeout() 對應的callback」放入 Callback Queue,而不會被 JavaScript 立即執行。

回到JavaScript 堆疊(Call Stack)這邊,當呼叫堆疊內都執行完畢(堆疊為空時),就會從 Callback Queue 依序取出 callback 並執行。

另外,關於上圖 Callback Queue 中的 MacrotaskMicroTask ,是兩種非同步操作的類型,它們有不同的執行順序和優先級。這留到明天再談。

以下是以動圖的方式呈現的範例。 (圖片來源

關於以上動圖的畫面,其實是一個叫做 Loupe 的網站,這個視覺化小工具,可以幫助我們了解 JavaScript 的Call Stack(呼叫堆疊)Web ApisCallback Queue(回調佇列)如何互動的,讓我們可以更清楚 事件循環(Event Loop) 的運作過程。

另外 Loupe 網站中提到的影片「所以說event loop到底是什麼玩意兒?」中詳細介紹了 Event Loop 的運作
原理,更是非常值得一看。

那麼今天就到這邊,明天見~


上一篇
[Day 08] JavaScript 中的同步(synchronous)和非同步(asynchronous)
下一篇
[Day 10] 非同步任務的兩種類型:Macrotask 與 MicroTask
系列文
複習 JavaScript 核心概念30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言