Иногда коду нужно немного подождать: показать уведомление через три секунды, запустить анимацию с паузами, опросить сервер раз в минуту. В большинстве языков для этого есть функция sleep() — остановить выполнение на нужное время. В JS её нет. Но есть setTimeout — и это интереснее, чем кажется на первый взгляд. В статье разберём js setTimeout, js sleep и как правильно делать паузы в JavaScript.
setTimeout в JavaScript — отложить на потом
setTimeout принимает два аргумента: функцию, которую нужно выполнить, и задержку в миллисекундах (1000 мс = 1 секунда). Вызов не блокирует остальной код — он просто говорит браузеру: «через столько-то миллисекунд запусти вот это»:
// Через 3 секунды выведет сообщение
setTimeout(() => {
console.log('Привет через 3 секунды!');
}, 3000);
// Этот код выполнится сразу, не дожидаясь таймера
console.log('Я выполнюсь первым'); Обратите внимание на порядок: «Я выполнюсь первым» появится раньше, чем «Привет через 3 секунды». Это ключевое свойство setTimeout — он не останавливает выполнение, а лишь планирует вызов на будущее.
Функцию можно передать по имени — результат тот же:
function showAlert() {
alert('Время вышло!');
}
// Передаём имя функции без скобок — скобки добавит setTimeout сам
setTimeout(showAlert, 5000); Если написать setTimeout(showAlert(), 5000) — со скобками — функция выполнится немедленно, а не через 5 секунд. Скобки означают «вызови прямо сейчас». Без скобок — «вот функция, вызови её потом».
setInterval — повторять снова и снова
setInterval работает как setTimeout , но не останавливается после первого вызова — запускает функцию снова и снова с указанным интервалом. Удобно для часов, счётчиков, автообновления данных:
// Выводим текущее время каждую секунду
const timerId = setInterval(() => {
const now = new Date();
console.log(now.toLocaleTimeString()); // например, «14:32:07»
}, 1000); setInterval возвращает числовой идентификатор таймера — он нужен, чтобы потом остановить интервал. Без остановки он будет работать вечно, пока открыта вкладка. Как надоедливый будильник, который никто не выключил.
clearTimeout и clearInterval — остановить таймер
Оба метода возвращают идентификатор — сохраните его в переменную, и сможете отменить таймер в любой момент с помощью clearTimeout или clearInterval :
// Запускаем интервал
const intervalId = setInterval(() => {
console.log('тик');
}, 1000);
// Через 5 секунд останавливаем
const stopId = setTimeout(() => {
clearInterval(intervalId);
console.log('остановили');
}, 5000);
// Отменить ещё не сработавший setTimeout тоже можно
clearTimeout(stopId); Важная деталь: clearTimeout и clearInterval взаимозаменяемы — технически это один механизм. Но для читаемости кода лучше использовать подходящий по смыслу метод.
Почему в JavaScript нет функции sleep()?
JavaScript — однопоточный язык. Это значит, что он выполняет только одно действие за раз — как повар-одиночка на кухне. Он не может одновременно нарезать овощи и жарить стейк: сначала одно, потом другое.
Если бы в JavaScript была настоящая sleep() — она бы буквально замораживала весь браузер. Пока «спит» ваш код, не обрабатываются клики, не обновляется страница, не работают анимации. Вкладка зависает. Именно поэтому браузеры убрали возможность блокирующего ожидания.
Вместо этого JavaScript использует событийный цикл: вместо того чтобы ждать, он говорит «сделай это через N миллисекунд» и продолжает заниматься другими делами. Повар ставит таймер и не стоит столбом у плиты — продолжает готовить остальные блюда, а когда таймер зазвонит, возвращается к нужной задаче.
Единственный способ «заблокировать» поток в JavaScript — это намеренно запустить бесконечный цикл. Браузер это заметит и предложит закрыть вкладку. Так что не надо.
JavaScript sleep — как сделать паузу в коде
Хорошая новость: имитировать sleep() всё-таки можно — через Promise и async/await . Браузер не замёрзнет: пока «спит» ваша функция, остальной код продолжает работать.
// Создаём функцию sleep — она возвращает Promise,
// который разрешается через указанное число миллисекунд
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
} Использовать её нужно с await внутри async -функции. await приостанавливает именно эту функцию — но не весь браузер:
async function showSteps() {
console.log('Шаг 1');
await sleep(1000); // пауза 1 секунда
console.log('Шаг 2');
await sleep(2000); // пауза 2 секунды
console.log('Шаг 3 — финал');
}
showSteps();
// Пока showSteps «спит», этот код спокойно выполняется
console.log('Я не жду никаких пауз'); В консоли сначала появится «Я не жду никаких пауз», затем через паузы — шаги 1, 2, 3. Функция showSteps ждёт, а остальной код — нет.
Практические примеры
Посмотрим, где таймеры и sleep применяются на практике.
Debounce — не реагировать на каждое нажатие клавиши. Если пользователь вводит текст для поиска, не нужно отправлять запрос на сервер при каждом нажатии. Лучше подождать, пока он закончит печатать:
function debounce(fn, delay) {
let timer;
return function(...args) {
clearTimeout(timer); // сбрасываем предыдущий таймер
timer = setTimeout(() => fn(...args), delay); // ставим новый
};
}
const onSearch = debounce((query) => {
console.log('Ищем:', query); // вызовется только через 500 мс после последнего ввода
}, 500);
document.querySelector('input').addEventListener('input', e => onSearch(e.target.value)); Retry с задержкой — повторить запрос при ошибке. Если сервер не отвечает, не нужно бомбардировать его мгновенными повторами — лучше подождать секунду и попробовать снова:
async function fetchWithRetry(url, attempts = 3) {
for (let i = 0; i < attempts; i++) {
try {
const res = await fetch(url);
return await res.json(); // успех — возвращаем результат
} catch (err) {
if (i < attempts - 1) {
console.log(`Попытка ${i + 1} не удалась, повтор через 1 сек...`);
await sleep(1000); // ждём перед следующей попыткой
}
}
}
throw new Error('Все попытки исчерпаны');
} Пошаговая анимация. sleep удобен для простых последовательных эффектов, когда не нужен сложный CSS:
async function typeText(element, text, delay = 60) {
element.textContent = '';
for (const char of text) {
element.textContent += char; // добавляем по одному символу
await sleep(delay); // пауза между символами
}
}
const el = document.querySelector('.js-typewriter');
typeText(el, 'Привет, мир!'); Итого: setTimeout и sleep в JavaScript
JavaScript не умеет спать — как хороший разработчик на дедлайне. Зато умеет планировать: откладывать задачи, повторять их и отменять.
- setTimeout(fn, ms) — выполнить один раз через задержку.
- setInterval(fn, ms) — выполнять повторно с интервалом.
- clearTimeout / clearInterval — отменить таймер по идентификатору.
- sleep(ms) через Promise + await — современный способ сделать паузу без заморозки браузера.
Если хотите разобраться с промисами подробнее — у нас есть отдельная статья: Promise в JavaScript простыми словами. Там разбираем, что такое промис, как работают .then() и .catch() , чем отличается Promise.all от последовательного await и где промисы применяются в реальных проектах.