intermediate
Timers
Используйте setTimeout, setInterval, setImmediate, timer promises, ref/unref, cancellation и scheduling limits осознанно.
Таймеры Node планируют колбэки в event loop — это не гарантия реального времени.
| API | Фаза / поведение | |-----|------------------| | `setTimeout` | фаза timers; минимальная задержка, не точная | | `setInterval` | повтор; колбэки могут накладываться, если work медленнее интервала | | `setImmediate` | фаза check; после I/O в том же витке | | `timers.promises.setTimeout` | на Promise; удобно с async/await |
`timeout.unref()` позволяет процессу завершиться, если остался только этот таймер — для фонового housekeeping. `ref()` удерживает event loop.
const t = setInterval(() => work(), 100);
function shutdown() {
clearInterval(t);
}
При нагрузке накапливается дрейф: интервал 100 ms не даёт ровно 10 вызовов в секунду, если `work()` занимает 80 ms.
На интервью: `setTimeout(0)` vs `setImmediate`; `unref` для корректного выхода; почему `setInterval` плох для точного расписания.
Типовые ошибки: «забытые» таймеры мешают shutdown; `setInterval` вместо рекурсивного `setTimeout` для backoff; нет `clearTimeout` на горячих путях.
Компромисс — между простотой, производительностью, безопасностью и эксплуатацией: назовите, что оптимизировали и какую цену приняли.
Чеклист:
- Сопоставьте API с фазой event loop.
- Снимайте таймеры при shutdown и в тестах.
- `unref` — только при осознанной семантике выхода.
- Тяжёлую периодику — в очереди, не в interval.