event loop

by Aaron • 10/13/2022, 4:27:55 AM

Javascript 是單線程序(single-threaded),一次只能執行一件任務。當有一個任務阻塞了就會導致後面的計算沒辦法被執行。Event loop 可以讓javascript 執行非同步的動作

Call-Stack (Last In First Out)

當執行func時,會將func push 到 call-stack 裡,並且在執行完該func時從call-stack pop。

console.log(1)
console.log(2)

Action:

  1. push console.log(1) to call-stack || call-stack: console.log(1)
  2. execute console.log(1), pop || call-stack: empty
  3. push console.log(2) to call-stack || call-stack: console.log(2)
  4. execute console.log(2), pop || call-stack: empty

micro task and macro task

  1. micro task: promise, queueMicrotask(func)
  2. macro task: setTimeout(func), …

當執行到micro/macro task時會push 到 micro/macro task queue. 當call-stack中的func都執行完變回empty時則先處理micro task queue 在執行macro task queue

例如

console.log(1);

setTimeout(() => console.log(2));

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

Promise.resolve().then(() => setTimeout(() => console.log(4)));

Promise.resolve().then(() => console.log(5));

setTimeout(() => console.log(6));

console.log(7);

Action:

  1. push console.log(1) 到 call-stack 執行並pop
  2. push setTimeout(() => console.log(2)) 到 macro task queue
  3. push () => console.log(3) 到 micro task queue
  4. push () => setTimeout(() => console.log(4)) 到 micro task queue
  5. push () => console.log(5) 到 micro task queue
  6. push setTimeout(() => console.log(6)) 到 macro task queue
  7. push console.log(7) 到 call-stack 執行並pop
  8. call-stack empty 開始清空micro task queue
  9. dequeue console.log(3) 到 call-stack,執行並pop
  10. dequeue setTimeout( () => console.log(4)) push 到 macro task queue
  11. dequeue console.log(6) 到 call-stack,執行並pop
  12. micro task queue empty 開始清空macro task queue
  13. dequeue console.log(2) 到 call-stack,執行並pop
  14. dequeue console.log(6) 到 call-stack,執行並pop
  15. dequeue console.log(4) 到 call-stack,執行並pop

output: 1 7 3 5 2 6 4

© 2025 Aaron Li. All Rights Reserved.