0
0
Lập trình
Harry Tran
Harry Tran106580903228332612117

Khám Phá Vòng Lặp Sự Kiện Trong JavaScript: Hiểu Rõ Bí Mật Của Đa Nhiệm

Đăng vào 1 tháng trước

• 3 phút đọc

Chủ đề:

Javascript

Khám Phá Vòng Lặp Sự Kiện (Event Loop) Trong JavaScript

Vòng lặp sự kiện là một trong những khái niệm quan trọng và thú vị nhất trong JavaScript, nhưng lại thường bị hiểu sai. Bài viết này sẽ giúp bạn nắm bắt được cơ chế hoạt động của vòng lặp sự kiện thông qua các ví dụ dễ hiểu, để bạn có thể áp dụng vào thực tế.

Vòng Lặp Sự Kiện Là Gì?

Bạn đã bao giờ thắc mắc làm thế nào JavaScript có thể xử lý nhiều tác vụ một cách hiệu quả mà chỉ có một luồng? Hãy cùng khám phá “ma thuật” của vòng lặp sự kiện trong JavaScript. Vòng lặp sự kiện hoạt động như một người quản lý tại một bữa tiệc, đảm bảo rằng mọi tác vụ đều được tiếp nhận và xử lý theo đúng thứ tự. Mặc dù JavaScript là ngôn ngữ đơn luồng, nó vẫn có khả năng tạo ra ảo giác về đa nhiệm nhờ vào vòng lặp sự kiện.

Cơ Chế Hoạt Động Của Vòng Lặp Sự Kiện

1. Mã Đồng Bộ

javascript Copy
console.log("1️⃣ Bắt đầu nấu ăn 🍳");  
console.log("2️⃣ Ăn sáng 🍴");  
console.log("3️⃣ Rửa chén 🧼"); 

Kết quả:

Copy
1️⃣ Bắt đầu nấu ăn 🍳  
2️⃣ Ăn sáng 🍴  
3️⃣ Rửa chén 🧼 

Giải thích:

Các tác vụ này được thực hiện một cách tuần tự (đồng bộ).

2. Tác Vụ Không Đồng Bộ Với setTimeout

javascript Copy
console.log("1️⃣ Bắt đầu nấu ăn 🍳");  

setTimeout(() => {  
  console.log("2️⃣ Ăn sáng 🍴 (sau 3 giây)");  
}, 3000);  

console.log("3️⃣ Rửa chén 🧼");  

Kết quả:

Copy
1️⃣ Bắt đầu nấu ăn 🍳  
3️⃣ Rửa chén 🧼  
2️⃣ Ăn sáng 🍴 (sau 3 giây)  

Giải thích:

  • Nhiệm vụ setTimeout sẽ được gửi đến Web API và không làm gián đoạn luồng chính.
  • Khi thời gian kết thúc, nó sẽ được chuyển vào hàng đợi để chờ luồng chính rảnh rỗi.
  • Vòng lặp sự kiện sẽ thực thi các nhiệm vụ đã được đưa vào hàng đợi sau khi xử lý xong các tác vụ đồng bộ.

3. Ưu Tiên Tác Vụ Nhỏ So Với Tác Vụ Lớn

javascript Copy
console.log("1️⃣ Bắt đầu 🍳");  

setTimeout(() => {  
  console.log("2️⃣ Macrotask: Thời gian chờ ⏳");  
}, 0);  

Promise.resolve().then(() => {  
  console.log("3️⃣ Microtask: Lời hứa ✅");  
});  

console.log("4️⃣ Kết thúc 🚀"); 

Kết quả:

Copy
1️⃣ Bắt đầu 🍳  
4️⃣ Kết thúc 🚀  
3️⃣ Microtask: Lời hứa ✅  
2️⃣ Macrotask: Thời gian chờ ⏳  

Giải thích:

Lệnh gọi lại từ Promise (microtask) sẽ được thực thi trước lệnh gọi lại từ setTimeout (macrotask), ngay cả khi độ trễ là 0ms.

4. Xử Lý Tác Vụ Nặng

Bạn đã bao giờ gặp tình trạng trang web bị đông cứng khi thực hiện tác vụ nặng chưa? Dưới đây là một ví dụ về mã không tối ưu:

javascript Copy
console.log("1️⃣ Bắt đầu 🏁");  

for (let i = 0; i < 1e9; i++) {}  // Giả lập tác vụ nặng  

console.log("2️⃣ Kết thúc 🛑"); 

Và đây là cách tối ưu bằng cách sử dụng setTimeout cho chunking:

javascript Copy
console.log("1️⃣ Bắt đầu 🏁");  

let count = 0;  

function heavyTask() {  
  if (count < 1e6) {  
    count++;  
    if (count % 100000 === 0) console.log(`Đã xử lý ${count} mục 🔄`);  
    setTimeout(heavyTask, 0); // Để vòng lặp sự kiện thở!
  } else {  
    console.log("2️⃣ Tác vụ hoàn thành ✅");  
  }  
}  

heavyTask();  

Tóm Tắt

1️⃣ JavaScript thực hiện mã đồng bộ trước khi xử lý bất kỳ tác vụ không đồng bộ nào.

2️⃣ Vòng lặp sự kiện sẽ quản lý và thực hiện các tác vụ không đồng bộ (như setTimeout).

3️⃣ Các tác vụ nhỏ (microtasks) sẽ được ưu tiên hơn các tác vụ lớn (macrotasks).

4️⃣ Chia nhỏ các tác vụ nặng ra thành các phần nhỏ để giữ cho giao diện người dùng luôn phản hồi tốt.
source: viblo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào