> Почему sleep(100) отработает примерно через 100 мс и может ли быть 99 мс? (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Яндекс

Стек: JavaScript

> Пример ответа

Короткий ответ

sleep(100) в JavaScript не гарантирует точного ожидания в 100 мс из-за особенностей event loop и таймеров. Минимальная задержка может быть чуть меньше из-за неточности таймеров, но 99 мс маловероятно. Фактическое время всегда ≥ указанного, но может быть больше из-за blocking операций в очереди задач.

Подробное объяснение

sleep(100) обычно реализуется через setTimeout или Promise с setTimeout. Таймеры в JavaScript не являются точными по нескольким причинам:

  1. Event loop: setTimeout не прерывает выполнение текущего кода, а ставит callback в очередь задач после указанной задержки. Если в очереди есть другие задачи, выполнение отложится.

  2. Минимальная задержка: В браузерах есть минимальный порог (обычно 4 мс для вложенных таймеров), а в Node.js - 1 мс.

  3. Clamping: Браузеры могут увеличивать задержку для неактивных вкладок (обычно до 1000 мс).

  4. Системные ограничения: Точность таймеров зависит от операционной системы и аппаратного обеспечения (обычно 1-15 мс).

Теоретически 99 мс возможно, если системный таймер имеет разрешение 1 мс и setTimeout(fn, 100) сработает чуть раньше из-за округления. На практике это крайне редко - большинство реализаций гарантируют, что задержка не меньше указанной.

На практике

В реальных проектах sleep используется для:

  • Имитации задержек в тестах
  • Throttling/debouncing запросов
  • Пауз между анимациями

Для точных временных интервалов лучше использовать performance.now() или requestAnimationFrame (в браузере). В Node.js есть setImmediate и process.nextTick для более точного контроля.

Пример кода

JAVASCRIPT
// Реализация sleep
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Измерение точности
async function testSleep() {
const start = performance.now();
await sleep(100);
const elapsed = performance.now() - start;
console.log(`Фактическая задержка: ${elapsed} мс`);
// Обычно 100-105 мс, редко 99-100 мс
}
// Более точная версия с performance.now
function preciseSleep(ms) {
const target = performance.now() + ms;
return new Promise(resolve => {
function check() {
if (performance.now() >= target) {
resolve();
} else {
requestAnimationFrame(check);
}
}
check();
});
}

Как отвечать на собеседовании

Начни с event loop и неточности таймеров. Упомяни, что sleep - это не нативная функция JS, а эмуляция через setTimeout. Объясни, почему 99 мс маловероятно, но теоретически возможно. Покажи понимание разницы между браузером и Node.js. Добавь про альтернативы для точных задержек.

Что проверяет интервьюер

  • Понимание event loop и очереди задач
  • Знание особенностей таймеров в JS
  • Умение объяснять асинхронность
  • Понимание системных ограничений
  • Способность оценивать точность операций

Типичные ошибки

  • Утверждение, что sleep гарантирует точное время
  • Игнорирование event loop и blocking операций
  • Путаница между setTimeout и setInterval
  • Незнание clamping в браузерах
  • Предположение, что sleep - нативная функция JS

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью