setTimeout(fn, 0) thực ra là setTimeout(fn, 1) tối thiểu, chạy ở timers phase khi timer đã hết hạn. setImmediate() chạy ở check phase, ngay sau poll phase.
Ngoài I/O context (ví dụ chạy thẳng trong main script) thứ tự giữa hai cái không đảm bảo — phụ thuộc độ phân giải đồng hồ hệ thống và thời gian dựng event loop. Nhưng bên trong một I/O callback thì setImmediate() LUÔN chạy trước, vì I/O callback nằm ở poll phase, sau poll là check phase rồi mới quay lại timers phase:
js
fs.readFile(file, () => {
setImmediate(() => console.log('immediate'))
setTimeout(() => console.log('timeout'), 0)
})
// luôn in: immediate → timeoutVì thế khi cần chạy code ngay sau thao tác I/O hiện tại nhưng trước mọi timer, dùng setImmediate.