← Назад к вопросам
В чем разница между setTimeout и setImmediate?
2.0 Middle🔥 181 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между setTimeout и setImmediate
setTimeout и setImmediate - это две функции для отложенного выполнения кода, но они работают по-разному и вписываются в Event Loop в разных местах.
Event Loop и очереди
JavaScript имеет несколько очередей для обработки кода:
┌─────────────────────────────┐
│ Synchronous Code │ (выполняется сразу)
├─────────────────────────────┤
│ Microtasks (Promises) │ (setInterval, .then())
├─────────────────────────────┤
│ setTimeout/setInterval │ (timer phase)
├─────────────────────────────┤
│ setImmediate (Node.js) │ (check phase)
├─────────────────────────────┤
│ Microtasks (после check) │
└─────────────────────────────┘
setTimeout
setTimeout помещает функцию в очередь таймеров. Она выполнится:
- После истечения времени (минимум 1-4 мс)
- После выполнения всех микротасков
- В следующем цикле Event Loop
console.log("1. Start");
setTimeout(() => {
console.log("4. setTimeout (через 0мс)");
}, 0);
Promise.resolve().then(() => {
console.log("3. Promise.then");
});
console.log("2. End");
// Вывод:
// 1. Start
// 2. End
// 3. Promise.then
// 4. setTimeout (через 0мс)
Почему Promise.then выполнится раньше setTimeout?
- Promises - это микротаски (выполняются в конце текущего цикла)
- setTimeout - это макротаск (выполняется в следующем цикле)
setImmediate (Node.js)
setImmediate доступен только в Node.js (не в браузере!). Она выполняется в фазе "check" Event Loop:
console.log("1. Start");
setImmediate(() => {
console.log("3. setImmediate");
});
setTimeout(() => {
console.log("2. setTimeout");
}, 0);
console.log("End");
// Node.js вывод:
// 1. Start
// End
// 2. setTimeout (timer phase)
// 3. setImmediate (check phase)
Детальное объяснение: Event Loop фазы в Node.js
┌───────────────────────────────┐
┌─>│ Timers (setTimeout, setInterval)│
│ └──────────────┬──────────────┘
│ │
│ ┌──────────────┴──────────────┐
│ │ Pending Callbacks │
│ └──────────────┬──────────────┘
│ │
│ ┌──────────────┴──────────────┐
│ │ Idle, Prepare │
│ └──────────────┬──────────────┘
│ │
│ ┌──────────────┴──────────────┐
│ │ Poll (I/O events) │
│ └──────────────┬──────────────┘
│ │
│ ┌──────────────┴──────────────┐
│ │ Check (setImmediate) │
│ └──────────────┬──────────────┘
│ │
│ ┌──────────────┴──────────────┐
│ │ Close Callbacks │
│ └──────────────┬──────────────┘
│ │
└─────────────────┘
Практический пример
// Node.js
setTimeout(() => {
console.log("A: setTimeout");
}, 0);
setImmediate(() => {
console.log("B: setImmediate");
});
Promise.resolve().then(() => {
console.log("C: Promise");
});
console.log("D: sync");
// Вывод:
// D: sync
// C: Promise (микротаск, выполняется первым после синхронного кода)
// A: setTimeout (timer фаза)
// B: setImmediate (check фаза)
Интересный момент: контекст вызова
setTimeout(() => {
console.log("setTimeout");
setImmediate(() => {
console.log("setImmediate в setTimeout");
});
}, 0);
setImmediate(() => {
console.log("setImmediate");
setTimeout(() => {
console.log("setTimeout в setImmediate");
}, 0);
});
// Вывод в Node.js:
// setTimeout
// setImmediate
// setImmediate в setTimeout
// setTimeout в setImmediate
Почему в таком порядке?
- Timer фаза: первый
setTimeoutвыполняется - В нём вызывается
setImmediate-> в очередь check фазы - Check фаза: первый
setImmediateвыполняется - В нём вызывается
setTimeout-> в очередь timer фазы - Timer фаза: второй
setTimeoutвыполняется - Check фаза: второй
setImmediateвыполняется
Таблица сравнения
| Характеристика | setTimeout | setImmediate |
|---|---|---|
| Доступность | Везде (браузер, Node) | Только Node.js |
| Время выполнения | После истечения (минимум 1мс) | После poll фазы |
| Относительная скорость | Медленнее | Быстрее (в Node.js) |
| Фаза Event Loop | Timer phase | Check phase |
| Отмена | clearTimeout() | clearImmediate() |
Почему это важно для производительности
// Плохо: setTimeout блокирует другие фазы Event Loop
function processHeavyTask() {
setTimeout(() => {
// Эта фаза ждёт время + микротаски
}, 0);
}
// Хорошо: setImmediate выполнится быстрее (в Node.js)
function processHeavyTask() {
setImmediate(() => {
// Эта фаза выполнится после poll
});
}
Браузер vs Node.js
В браузере setImmediate не существует!
// Браузер
console.log(typeof setImmediate); // undefined
// Node.js
console.log(typeof setImmediate); // function
В браузере для похожего результата используют:
- MessageChannel
- requestAnimationFrame
- Promise микротаски
// Браузерная альтернатива для "setImmediate"
const { port1, port2 } = new MessageChannel();
port1.onmessage = () => {
console.log("Выполнилось в check-подобной фазе");
};
setTimeout(() => {
port2.postMessage(null);
}, 0);
Вывод
- setTimeout - универсальное решение для отложенного выполнения (макротаск)
- setImmediate - только в Node.js, выполняется после I/O (check фаза)
- setImmediate быстрее в Node.js благодаря порядку фаз
- Promises выполняются раньше обоих (микротаски)
- В браузере setImmediate недоступен
Для практики: используй setTimeout для кроссбраузерности, setImmediate для Node.js оптимизации.