Vì hai hàm nằm ở hai phase khác nhau của event loop, và vị trí bạn gọi chúng quyết định phase nào đến trước.
Một vòng lặp đi qua các phase theo thứ tự: timers → pending callbacks → poll → check → close callbacks. setTimeout chạy ở timers, setImmediate chạy ở check.
Ở main module: khi vòng lặp bắt đầu, Node đã tốn một khoảng thời gian không đoán trước để khởi động tiến trình. Nếu khoảng đó ≥ 1ms thì timer đã "chín" ngay ở phase timers đầu tiên → timeout trước. Nếu chưa đủ 1ms thì phase timers trống, vòng lặp đi tiếp tới check → immediate trước. Chạy đi chạy lại sẽ thấy đổi thứ tự.
Trong callback I/O: callback đó đang chạy ở phase poll. Phase kế tiếp là check → setImmediate chạy ngay trong vòng lặp hiện tại; còn setTimeout phải chờ tới phase timers của vòng lặp sau. Nên immediate luôn thắng.
require('fs').readFile(__filename, () => {
setTimeout(() => console.log('timeout'), 0)
setImmediate(() => console.log('immediate'))
})
// always prints: immediate, then timeoutHệ quả thực dụng: muốn "chạy sau khi phần I/O hiện tại xong", dùng setImmediate — nó xác định, còn setTimeout(fn, 0) thì không.