JavaScript: Event Loop và Call Stack

Published on March 01, 2025

javascript

View: 123

JavaScript: Event Loop và Call Stack

JavaScript là ngôn ngữ đơn luồng (single-threaded), có nghĩa là nó chỉ có một Call Stack và thực thi từng dòng code một cách tuần tự. Tuy nhiên, nhờ vào Event Loop, JavaScript có thể xử lý các tác vụ bất đồng bộ như setTimeout, fetch, DOM events, I/O operations mà không bị chặn.


1. Call Stack (Ngăn xếp gọi hàm)

Call Stack là một cấu trúc dữ liệu LIFO (Last In, First Out) dùng để lưu trữ các lời gọi hàm. Khi một hàm được gọi, nó sẽ được push vào Call Stack, và khi hoàn thành, nó sẽ được pop ra khỏi Call Stack.

🔹 Cách hoạt động của Call Stack:

  1. Khi gọi một hàm, nó được đẩy vào Call Stack.

  2. Khi hàm hoàn tất, nó bị loại khỏi Call Stack.

  3. JavaScript tiếp tục thực thi các lệnh còn lại.

🔹 Ví dụ về Call Stack:

function foo() {
  console.log("Foo");
}

function bar() {
  foo();
  console.log("Bar");
}

bar();
console.log("Done");

🔽 Quá trình thực thi:

1. Gọi `bar()` → Push `bar` vào Call Stack  
2. `bar` gọi `foo()` → Push `foo` vào Call Stack  
3. `foo` chạy `console.log("Foo")` → In ra màn hình → Pop `foo` khỏi Call Stack  
4. `bar` chạy tiếp `console.log("Bar")` → In ra màn hình → Pop `bar` khỏi Call Stack  
5. `console.log("Done")` → In ra màn hình  

Output trên console:

Foo
Bar
Done

2. Event Loop

JavaScript xử lý bất đồng bộ bằng Event Loop, giúp kiểm tra Call Stack và xử lý các tác vụ bất đồng bộ từ Web APIsCallback Queue.

🔹 Cấu trúc chính của Event Loop gồm:

  1. Call Stack (Chạy code đồng bộ)

  2. Web APIs (Xử lý bất đồng bộ như setTimeout, fetch, DOM events)

  3. Callback Queue (Chứa các callback chờ thực thi)

  4. Event Loop (Kiểm tra nếu Call Stack rỗng thì đưa callback từ Queue vào Call Stack)

🔹 Ví dụ về Event Loop với setTimeout:

console.log("Start");

setTimeout(() => {
  console.log("Inside setTimeout");
}, 0);

console.log("End");

🔽 Quá trình thực thi:

  1. console.log("Start") → In "Start"

  2. setTimeout(() => console.log("Inside setTimeout"), 0) → Gửi đến Web API để chờ

  3. console.log("End") → In "End"

  4. Event Loop thấy Call Stack rỗng → Đưa callback từ Callback Queue vào Call Stack

  5. console.log("Inside setTimeout") → In "Inside setTimeout"

Output trên console:

StartEnd
Inside setTimeout

📌 Lưu ý:setTimeout có thời gian là 0ms, nó vẫn được đưa vào Callback Queue và phải đợi Call Stack rỗng để thực thi.


3. Microtask Queue vs Callback Queue

🔹 Microtask Queue (Ưu tiên cao hơn Callback Queue) chứa:

  • Promise.then(), MutationObserver, queueMicrotask

  • Chạy ngay lập tức sau khi Call Stack rỗng, trước cả Callback Queue.

🔹 Callback Queue chứa:

  • setTimeout, setInterval, setImmediate, DOM Events

  • Chạy sau khi Microtask Queue trống.

🔹 Ví dụ minh họa:

console.log("Start");

setTimeout(() => {
  console.log("setTimeout");
}, 0);

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

console.log("End");

Output trên console:

Start
End
PromisesetTimeout

📌 Giải thích:

  1. console.log("Start")"Start"

  2. setTimeout(..., 0) → Đưa vào Callback Queue

  3. Promise.resolve().then(...) → Đưa vào Microtask Queue

  4. console.log("End")"End"

  5. Microtask Queue (Promise.then(...)) chạy trước → "Promise"

  6. Callback Queue (setTimeout) chạy sau → "setTimeout"


4. Tổng kết

Call Stack: Thực thi mã JavaScript theo kiểu đồng bộ.
Event Loop: Kiểm tra Call Stack và xử lý bất đồng bộ.
Web APIs: Chạy các tác vụ như setTimeout, fetch, DOM Events.
Microtask Queue ưu tiên hơn Callback Queue.
Promise chạy trước setTimeout vì Microtask chạy trước Callback Queue.


🚀 Câu hỏi phỏng vấn thường gặp về Event Loop

  1. Sự khác biệt giữa Call Stack và Event Loop là gì?
    ➜ Call Stack xử lý các lệnh đồng bộ, còn Event Loop giúp JavaScript xử lý các tác vụ bất đồng bộ.

  2. Promise và setTimeout cái nào chạy trước?
    Promise.then() chạy trước vì nó nằm trong Microtask Queue, còn setTimeout chạy sau trong Callback Queue.

  3. setTimeout với thời gian là 0ms có chạy ngay lập tức không?
    ➜ Không! Nó phải chờ Call Stack rỗng và chạy sau các tác vụ trong Microtask Queue.

Bạn có muốn thêm ví dụ nào khác không? 🚀

Related Articles

How to Improve Your Blog Design

Learn tips and tricks to enhance your blog's appearance and usability.

Top Blogging Tools in 2024

Discover the best tools to elevate your blogging experience.

Writing Content that Converts

Learn the art of creating engaging and effective blog content.

Ôn tập là dễ

Ôn tập là dễ

Nền tảng thi trắc nghiệm số 1 Việt Nam giúp bạn tạo, quản lý và chia sẻ bộ đề một cách nhanh chóng và dễ dàng.

© 2025 Ôn tập là dễ. Tất cả các quyền được bảo lưu.