JavaScript Event loop 三歲小孩解釋法!

三歲小孩解釋版的 Event Loop

想像你在玩一個「煮泡麵」的遊戲,你有一個超級忙碌的廚房,但這個廚房 一次只能做一件事(這就是 JavaScript 的「單執行緒」)。


1. 同步(Synchronous)—— 一件事做完才能做下一件

你開始煮泡麵:

  1. 先把水倒進鍋子

  2. 開火加熱水

  3. 水滾了再放泡麵

  4. 等 3 分鐘

  5. 泡麵煮好了,關火,開吃!

這就是 同步,所有事情都要 一件做完才做下一件,如果等水滾的時候什麼都不能做,那就超級無聊!


2. 異步(Asynchronous)—— 可以同時做別的事

但是你發現:「為什麼要乾等 3 分鐘?」所以你決定利用時間去做其他事情:

  1. 把水倒進鍋子,開火煮水(這需要時間)

  2. 等水滾的時候,先去洗碗

  3. 再去切小菜

  4. 等水滾了,把泡麵放進去(繼續等)

  5. 再去倒飲料

  6. 泡麵好了,關火,開吃!

這就是 異步,你可以一邊等水滾,一邊做別的事情,不會浪費時間。


3. Event Loop(事件循環)—— 廚房小助手

但是,怎麼確保泡麵不會煮到忘記呢?這時候你的 小助手「事件循環」 就會幫你看著鍋子:

  • 如果水還沒滾,繼續做別的事

  • 一旦水滾了,小助手提醒你:「水滾了!該放泡麵了!」

  • 之後再提醒你:「3 分鐘到了!泡麵好了!」

這就是 事件循環(Event Loop),它的工作就是:

  1. 先把該做的事情 (同步的事) 做完

  2. 然後去看有沒有事情 (異步的事) 完成了

  3. 如果有,就趕快去做!


4. 宏任務(Macro Task)和微任務(Micro Task)—— 事情的優先順序

但有時候,你的事情還有「重要性」的差別,比如:

  • 微任務(Micro Task):超級緊急的事情,例如「先加調味粉」,這些事情 一定要馬上做!

  • 宏任務(Macro Task):普通的事情,例如「等 3 分鐘」,這種事情可以排隊等一下。

所以 JavaScript 會先做「微任務」,再做「宏任務」。

舉例

js複製編輯console.log(1); 

setTimeout(() => {
  console.log(2);
}, 0);

Promise.resolve()
  .then(() => {
    console.log(3);
  })
  .then(() => {
    console.log(4);
  });

輸出順序是:

複製編輯1
3
4
2

因為:

  1. console.log(1) 直接執行

  2. setTimeout宏任務,所以等一下

  3. Promise.then微任務,所以 比 setTimeout 先執行!

  4. console.log(3)console.log(4) 先執行完 微任務

  5. console.log(2) 最後才執行(因為 setTimeout下一輪 才跑)


5. requestAnimationFrame 和 requestIdleCallback

  • requestAnimationFrame:瀏覽器畫面更新前執行(畫圖前的準備)

  • requestIdleCallback:等瀏覽器有空再執行(等於「有空再來做」)


總結

事件循環就像一個 廚房小助手,會幫你安排事情:

  • 先做同步的事(直接執行)

  • 遇到異步的事,讓它排隊

  • 先處理 微任務

  • 再來處理 宏任務

  • 重複這個過程,讓程式運作流暢不卡住!

這樣懂了嗎?😆