Event Loop là gì? Cơ chế hoạt động của Event Loop trong JavaScript

- Published on
- /6 phút đọc/---
1. Event Loop là gì
Event Loop là một cơ chế cho phép xử lý các tác vụ bất đồng bộ trong Javascript, sử dụng một vòng lặp vô hạn để kiểm tra, quản lý các tác vụ. Javascript có thể xử lý nhiều tác vụ cùng lúc mặc dù JavaScript là single-threaded - tại một thời điểm chỉ thực hiện một tác vụ duy nhất.
2. Tại sao Event Loop lại quan trọng?
- Tránh tình trạng ứng dụng bị treo: Xử lý các tác vụ bất đồng bộ mà không làm nghẽn luồng chính.
- Xử lý bất đồng bộ: Xử lý tác vụ bất đồng bộ như là call API hay thao tác với cơ sở dữ liệu à không làm chậm chương trình.
- An toàn khi thực thi tác vụ bất đồng bộ: Event Loop quản lý và điều phối quá trình thực thi các tác vụ không bị xung đột do việc chia sẻ tài nguyên trong Javascript.
- Kiểm soát quá trình thực thi: Hiểu sau về Event Loop, giúp các bạn dev dự đoạn được luồng thực thi, debug hiệu quả và nhanh chóng.
- Giao diện người dùng: Duy trì trải nghiệm cho người dùng khi có các tác vụ nặng.
- Nâng cao hiệu suất: Javascript có thể xử lý nhiều tác vụ hiệu quả hơn mà không cần phải tạo nhiều luồng, tiết kiệm tài nguyên của hệ thống.
3. Cơ chế hoạt động Event Loop trong JS
3.1 Call Stack
- Call stack là một thành phần quan trọng trong JS, quản lý việc thực thi tác vụ của chương trình.
- Khi một hàm được gọi trong Javascript, hàm đó sẽ được thêm vào call stack.
- Call stack hoạt động theo cơ chế FILO (First In Last Out).
- Khi hàm được thực hiện sẽ đẩy ra khỏi call stack.

Ví dụ Stack trong thực tế: Khi chúng ta bỏ các cái bánh vào một chiếc hộp, hành động bỏ vào tương tự như Push trong Stack, vì chúng ta sẽ bỏ lần lượt từng cái bánh vào trên đỉnh của chiếc hộp. Và khi ta muốn lấy bánh ra ta cũng sẽ phải lấy cái ở trên đỉnh ra trước, hành động này tương tự như Pop trong Stack.

Chức năng respond
trả về một function setTimeout
. SetTimeout được cung cấp cho chúng ta bởi API Web: Nó cho phép chúng ta trì hoãn các tác vụ mà không chặn luồng chính. Callback function mà chúng ta đã chuyển vào hàm setTimeout
, arrow function () => {return 'hey'}
được thêm vào API web. Trong thời gian chờ đợi, function SetTimeout và function respond
bị lấy ra khỏi ngăn xếp và return giá trị của chúng

Trong thực tế khi xây dựng chương trình sẽ có nhiều tác vụ chạy lâu hơn. Điều này có khiến cho toàn bộ ứng dụng treo không
May mắn, câu trả lời là không! Chức năng này thực ra không phải là một phần của Javascript; Browser hỗ trợ WebAPIs
3.2 Web APIs
Web API cung cấp toàn bộ giao diện tương tác bao gồm các tính năng như: fecth, setTimeout và một vài tính năg khác.

Trong API Web, bộ đếm thời gian chạy trong khoảng thời gian bằng với đối số thứ hai mà chúng ta đã chuyển cho nó, 1000 mili giây. Callback function không ngay lập tức được thêm vào call stack, thay vào đó, nó được chuyển đến một thứ gọi là queue (hàng đợi).

Có thể bạn sẽ khó hiểu một chút ở đây: Khi callback function được đưa vào queue, điều đó không có nghĩa là callback function được thêm vào call stack sau 1000 mili giây! Nó chỉ đơn giản là được thêm vào queue sau 1000 mili giây. Nhưng đó là một queue, và function phải chờ đến lượt của nó!
3.3 Event Loop
Đây chính là trách nhiệm của Event Loop, nó có nhiệm vụ liên tục kiểm tra xem call stack có trống không.
Bây giờ chúng ta sẽ chờ đến đúng thời gian để Even Loop gọi callback function của mình: kết nối queue với call stack. Nếu call stack trống, khi mà tất cả các function trong stack đã được gọi và được lấy ra khỏi call stack, item đầu tiên trong queue sẽ được thêm vào call stack. Trong trường hợp này, không có function nào khác được gọi, có nghĩa là call stack trống vào thời điểm callback function là mục đầu tiên trong hàng đợi.

callback được thêm vào call stack, được gọi và trả về một giá trị và được đưa ra khỏi ngăn xếp.

Có thể tới đây bạn đã hiểu về Event Loop cũng như Call stack trong javascript, nhưng hãy thử một vài ví dụ sau, cố gắng tìm ra những gì sẽ xuất hiện trong bảng điều khiển nếu chúng ta chạy mã sau:
const foo = () => console.log("First");
const bar = () => setTimeout(() => console.log("Second"), 500);
const baz = () => console.log("Third");
bar();
foo();
baz();
Bạn đã có mã của mình chưa? Hãy nhanh chóng xem điều gì đang xảy ra khi chúng ta chạy mã này trong trình duyệt:

- Chúng ta gọi function
bar
.bar
trả về một hàmsetTimeout
. - callback mà chúng ta đã chuyển đến
setTimeout
được thêm vào API Web, chức năngsetTimeout
vàbar
sẽ được lấy ra khỏi call stack. - Đồng hồ bấm giờ chạy, trong khi chờ đợi,
foo
được gọi và vào consoleFirst
.foo
trả về (undefined
),baz
được gọi và callback được thêm vào call stack. baz
sẽ xuất ra consoleThird
. Event Loop thấy call stack trống sau khibaz
được gọi, sau đó callback được thêm vào call stack.- Cuối cùng console xuất
Second
.
5. Kết luận
- Hiểu rõ JavaScript asynchronous và non-blocking, biết cách Event Loop, Task Queue, và Microtask Queue làm việc cùng nhau.
- Event Loop quản lý thứ tự thực hiện các công việc, ưu tiên Microtask Queue trước để đảm bảo các promises và các tác vụ liên quan được xử lý nhanh chóng, sau đó mới đến các công việc trong Task Queue.
- Cách hoạt động này giúp cho JavaScript xử lý các thao tác không đồng bộ phức tạp trong môi trường đơn luồng.