JS的同步非同步與Event Loop


Posted by Andy Tsai on 2020-04-12

同步非同步

有些人會說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。

範例動畫流程

動畫取自 JavaScript Visualized: Event Loop

  1. greet函式被調用,return 'Hello!',彈出Stack;
    respond函式被調用,return一個setTimeout

  2. 由於respond函式return了一個非同步行為(setTimeout),所以會把setTimeout轉交給Web Api處理,接著respond()彈出Stack

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

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

  5. 在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


#w3HexSchool #javascript #Event Loop #Event Queue







Related Posts

Tailwind CSS 引用 (使用nuxt)

Tailwind CSS 引用 (使用nuxt)

使用JavaScript更改CSS偽元素

使用JavaScript更改CSS偽元素

[筆記] React.memo / useMemo / useCallback

[筆記] React.memo / useMemo / useCallback


Comments