Как сделать паузу (sleep) в JavaScript? Нужен аналог sleep() из других языков
Проблема: JavaScript — асинхронный по своей природе
В отличие от Python или PHP, JavaScript (особенно в браузере) не блокирует поток выполнения. Функции вроде setTimeout или setInterval не останавливают код, а ставят задачу в очередь событий. Поэтому ваш код выполняется мгновенно.
Современное решение: промисы и async/await
Начиная с ES2017, в JavaScript появилась конструкция async/await, которая позволяет писать асинхронный код так, как будто он синхронный. Вам нужно создать функцию, которая возвращает промис, разрешающийся через заданное количество миллисекунд.
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Использование с async/await
async function main() {
console.log("Начинаем");
await sleep(2000); // Ждём 2 секунды
console.log("Прошло 2 секунды");
}
main();
Как это работает
new Promise(resolve => setTimeout(resolve, ms))— создаёт промис, который "разрешится" (вызоветresolve) черезmsмиллисекунд.awaitприостанавливает выполнение асинхронной функции до тех пор, пока промис не будет разрешён.- Функция
mainдолжна быть объявлена какasync, чтобы внутри неё можно было использоватьawait.
Альтернатива: синхронный sleep (НЕ РЕКОМЕНДУЕТСЯ)
В Node.js есть синхронная функция Atomics.wait() или утилита sleep из пакета timers/promises (с Node 15+), но она блокирует главный поток. В браузере синхронного sleep нет, и его не стоит делать, так как это заморозит интерфейс.
// Node.js (только для скриптов, не для серверов!)
const { setTimeout } = require('timers/promises');
async function main() {
console.log("Начинаем");
await setTimeout(2000);
console.log("Прошло 2 секунды");
}
Практический пример: повтор с задержкой
Часто sleep используют в циклах, например, для опроса сервера:
async function pollServer() {
for (let i = 0; i < 5; i++) {
console.log(`Попытка ${i + 1}`);
// Здесь мог быть fetch()
await sleep(1000); // Ждём 1 секунду между попытками
}
console.log("Опрос завершён");
}
Важные замечания
awaitработает только внутриasyncфункций.- Не пытайтесь сделать
sleepс помощью цикловwhile(Date.now() < deadline)— это заблокирует процесс и может повесить браузер. - В современных проектах используйте
import { setTimeout } from 'timers/promises'(Node.js) или обёртку сPromise(универсально).
Итог: правильный способ сделать паузу в JavaScript — это комбинация Promise + setTimeout + async/await. Это не блокирует поток и работает везде.
Альтернативный подход: sleep без async/await (только промисы)
Если вы не можете использовать async/await (например, работаете со старым кодом или в среде без поддержки ES2017), можно использовать цепочку промисов:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
console.log("Начинаем");
sleep(2000).then(() => {
console.log("Прошло 2 секунды");
});
Этот код делает то же самое, но без async. Метод .then() выполнится только после того, как промис разрешится через 2 секунды.
Дополнение: утилита для повторяющихся действий
Вы можете создать обёртку для выполнения задачи с задержкой после каждого вызова:
function withDelay(fn, ms) {
return async (...args) => {
await sleep(ms);
return fn(...args);
};
}
const delayedLog = withDelay(console.log, 1000);
delayedLog("Это сообщение появится через 1 секунду");
Этот паттерн удобен для rate-limiting (ограничения частоты вызовов) при работе с API.