JS的同步非同步與Event Loop
同步非同步
有些人會說 JavaScript 是非同步的語言
不過要精確點說的話
JS 是一個 Single Thread(單執行緒)語言,一次只會做一件事,
所以 JS 本身是同步的語言,只是它具有非同步的特性
這是為了符合瀏覽器的使用情境,JS 需要具有非同步的能力,而要達到非同步,靠的就是 Event Loop
Event Loop 運行機制

在 JS 執行緒中,有 Heap 和 Stack,Heap 是處理記憶體分配的地方,
而在 Stack 中,就是所有的 JS 任務,每個任務執行完後就會彈出 Stack。
流程是,JS 執行緒會逐一執行 Stack 內的程式,當遇到非同步行為時(例如 setTimeout),它就會把它推到 Event Queue(就是上圖中的 Callback Queue)裡,然後等 Stack 裡的程式都跑完 清空了,就會開始逐一執行 Event Queue 中的任務,Queue 是先進先出的資料結構,所以先進來的函式會先被執行。
這個過程是不斷循環的,所以這機制又稱為 Event Loop。
範例動畫流程
- greet 函式被調用,return ‘Hello!’,彈出 Stack;
respond 函式被調用,return 一個 setTimeout
- 由於 respond 函式 return 了一個非同步行為(setTimeout),所以會把 setTimeout 轉交給 Web Api 處理,接著 respond()彈出 Stack

- 設定的 1 秒到了,添加到 Event Queue 裡

- 如果 Stack 為空,那麼 Event Queue 中的第一項將被添加到 Stack

- 在 Stack 中 return ‘Hey’,彈出 Stack

簡單題目測試
這段程式輸出的結果是?
function test(){
console.log('a')
setTimeout(() => {
console.log('b')
}, 0)
console.log('c')
}
test()答:
a
c
b
因為 b 是一個非同步事件,他會被放到 Event Queue 裡,
也就是說,它在所有程式執行完(Stack 清空)後才會執行,所以答案就是 a->c->b
Reference:
https://www.youtube.com/watch?v=8aGhZQkoFbQ
https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif
