同步非同步
有些人會說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