event loop

by Aaron • 10/13/2022, 2:27:55 PM

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.