Сравни способы реализовать таймер чтобы было точное время и объясни, когда выбирать каждый вариант.
Асинхронность и Event Loop
Для точного таймера не полагаются на `setInterval` (накапливает дрейф), а корректируют по реальному времени (`Date.now`/`performance.now`), используют рекурсивный `setTimeout` с коррекцией или Web Worker.
Проблема setInterval
setInterval неточен: если основной поток занят, вызовы задерживаются и накапливают дрейф — таймер «уплывает»:
setInterval(tick, 1000); // за час может отстать на секундыСпособы точного таймера
Коррекция по реальному времени (рекомендуется)
Считать прошедшее время по Date.now(), а не по числу тиков — компенсировать дрейф:
const start = Date.now();
let expected = start + 1000;
function tick() {
const drift = Date.now() - expected;
updateUI(Date.now() - start); // реальное прошедшее время
expected += 1000;
setTimeout(tick, Math.max(0, 1000 - drift)); // коррекция
}
setTimeout(tick, 1000);Каждый шаг корректируется на накопленный дрейф.
performance.now() для точности
Высокоточное монотонное время (не зависит от системных часов):
const start = performance.now();
// elapsed = performance.now() - startWeb Worker
Таймер в отдельном потоке — не блокируется тяжёлым UI основного потока (меньше дрейф):
// worker.js крутит таймер, шлёт тики в основной потокrequestAnimationFrame
Для визуальных таймеров, синхронных с кадрами (но паузится в фоне).
Как выбирать
- Точный таймер/секундомер → коррекция по `Date.now`/`performance.now`.
- Не блокировать при тяжёлом UI → Web Worker.
- Визуальная анимация таймера → requestAnimationFrame.
Коротко для собеседования
setInterval неточен (накапливает дрейф при занятом потоке). Для точного времени: считать по реальному времени (Date.now()/performance.now()), а не по числу тиков; рекурсивный setTimeout с коррекцией на дрейф; Web Worker (таймер вне основного потока, меньше блокировок). performance.now — монотонное высокоточное время.