Event loop là vòng lặp chạy liên tục, xử lý callback qua sáu phase:
1. Timers — chạy callback của setTimeout/setInterval đã đến hạn.
2. Pending callbacks — lỗi I/O còn tồn từ vòng trước.
3. Idle/prepare — dùng nội bộ.
4. Poll — nhận I/O event mới; nếu queue rỗng và không còn timer nào chờ, event loop nằm chờ I/O ngay tại đây.
5. Check — callback của setImmediate.
6. Close callbacks — socket.on('close').
Giữa mỗi phase, Node.js dọn sạch hàng đợi process.nextTick() trước — đây là hàng đợi riêng của Node, không phải microtask của V8 — rồi mới đến microtask queue: callback của Promise (then/catch) và queueMicrotask().
setTimeout(A, 0) // phase Timers
Promise.resolve().then(B) // microtask
process.nextTick(C) // hàng đợi riêng của Node, không phải microtask của V8
// thứ tự chạy trong CommonJS: C → B → A (trong ES module là B → C → A)Lưu ý: microtask queue mà không bao giờ rỗng (Promise resolve xong lại tạo Promise mới) thì event loop kẹt luôn, không bao giờ sang được phase kế tiếp — đây gọi là starvation.