Menu
CoddyTech

Event Loop

Thuộc phần Kiến thức cơ bản về Node.js trong hành trình Node.js của Coddy. Bài học 26 trên 33.

Callback và promise chạy sau, và bug thường xuất hiện khi bạn không biết chính xác chúng chạy lúc nào.

Node chạy hết toàn bộ code đồng bộ trước. Sau đó, Node chạy các tác vụ vi mô: callback của promise và các hàm được truyền vào queueMicrotask. Tiếp theo mới đến các bộ hẹn giờ. setTimeout(fn, ms) chạy fn một lần, sau ms mili giây. Ngay cả setTimeout(fn, 0) cũng chờ đến khi các tác vụ vi mô chạy xong.

setTimeout(() => console.log('C timer'), 0);
Promise.resolve().then(() => console.log('B promise'));
console.log('A sync');
// A sync, B promise, C timer

Độ trễ 0 nghĩa là chạy sớm nhất có thể sau các tác vụ vi mô, không bao giờ chạy trước chúng. Các bộ hẹn giờ chạy theo thứ tự độ trễ; nếu độ trễ bằng nhau, bộ hẹn giờ được đặt trước sẽ chạy trước.

challenge icon

Thử thách

Dễ

Node chạy code theo một thứ tự cố định. Trước tiên là các dòng thông thường, sau đó là các microtask như callback của promise, rồi đến các bộ hẹn giờ. Hãy dùng thứ tự đó để in bốn dòng theo thứ tự số mà không di chuyển chúng.

order.js in bốn dòng theo thứ tự từ 4 xuống 1. Đừng di chuyển hay sắp xếp lại các dòng. Thay vào đó, hãy bọc ba dòng để chúng chạy sau.

  1. Giữ nguyên console.log('1 sync'). Code thông thường chạy trước.
  2. Bọc dòng 2 microtask trong queueMicrotask để dòng đó chạy ngay sau code thông thường.
  3. Bọc riêng dòng 3 timeout và dòng 4 timeout later trong setTimeout. setTimeout(fn, ms) chạy hàm fn một lần sau ms mili giây. Dòng 4 được đặt trước dòng 3, vì vậy dòng 4 cần độ trễ dài hơn.

Sau đó, node order.js sẽ in ra:

1 sync
2 microtask
3 timeout
4 timeout later

Thử nhé: trước khi chạy, hãy đoán thứ tự. Sau đó nhấn Run; terminal hiển thị $ node order.js. Tiếp theo, đặt độ trễ của cả hai bộ hẹn giờ là 0 rồi chạy lại: lúc này 4 timeout later sẽ in ra trước 3 timeout, vì khi độ trễ bằng nhau, bộ hẹn giờ được đặt trước sẽ chạy trước. Đặt lại độ trễ dài hơn cho dòng 4 trước khi nhấn Kiểm tra.

Tự làm thử

// Bạn hãy để các dòng này in ra theo thứ tự số mà không di chuyển chúng.
// Thay vào đó, bọc chúng bằng queueMicrotask và setTimeout.
console.log('4 timeout later');
console.log('3 timeout');
console.log('2 microtask');
console.log('1 sync');
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Kiến thức cơ bản về Node.js

Tự luyện tập: Playground Express