Как написать Wait без использования Promise?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Как написать Wait (задержку) без использования Promise
В JavaScript есть несколько способов добавить задержку без использования Promise. Рассмотрим основные подходы.
1. setTimeout с callback функцией
setTimeout — это самый основной способ добавить асинхронную задержку. Он выполняет функцию через указанное время.
// Простая задержка
setTimeout(() => {
console.log('Выполнилось через 2 секунды');
}, 2000);
// С параметрами
setTimeout((name) => {
console.log(`Привет, ${name}!`);
}, 1000, 'Иван');
// С переменной
const delay = 3000;
setTimeout(() => {
console.log('Задержка в 3 секунды');
}, delay);
2. setInterval для повторяющейся задержки
setInterval — выполняет функцию многократно через равные промежутки времени.
let counter = 0;
const intervalId = setInterval(() => {
counter++;
console.log(`Счётчик: ${counter}`);
// Остановить интервал при достижении 5
if (counter === 5) {
clearInterval(intervalId);
console.log('Интервал остановлен');
}
}, 1000);
3. setTimeout с рекурсией
Можно создать функцию, которая повторяет действие через задержку:
function repeatWithDelay(callback, delay, times) {
let count = 0;
function execute() {
callback(count);
count++;
if (count < times) {
setTimeout(execute, delay);
}
}
execute();
}
// Использование
repeatWithDelay((i) => {
console.log(`Итерация ${i + 1}`);
}, 1000, 5);
// Выведет:
// Итерация 1
// Итерация 2
// Итерация 3
// Итерация 4
// Итерация 5
4. requestAnimationFrame для плавной анимации
requestAnimationFrame — синхронизируется с частотой обновления браузера (обычно 60 FPS). Используется для анимаций.
let startTime = null;
const duration = 2000; // 2 секунды
function animate(currentTime) {
if (startTime === null) {
startTime = currentTime;
}
const elapsed = currentTime - startTime;
const progress = elapsed / duration; // 0 до 1
console.log(`Прогресс: ${(progress * 100).toFixed(1)}%`);
if (progress < 1) {
requestAnimationFrame(animate);
} else {
console.log('Анимация завершена');
}
}
requestAnimationFrame(animate);
5. Event Listeners с таймерами
Можно использовать события для триггера функций:
const button = document.querySelector('button');
let isWaiting = false;
button.addEventListener('click', () => {
if (isWaiting) {
console.log('Пожалуйста, подождите...');
return;
}
isWaiting = true;
console.log('Обработка запроса...');
setTimeout(() => {
isWaiting = false;
console.log('Запрос завершен!');
}, 3000);
});
6. Debounce функция (задержка выполнения)
Debounce — откладывает выполнение функции на заданное время. Если функция вызывается снова, таймер сбрасывается.
function debounce(callback, delay) {
let timeoutId = null;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
callback.apply(this, args);
}, delay);
};
}
// Использование
const input = document.querySelector('input');
const handleSearch = debounce((value) => {
console.log(`Поиск по: ${value}`);
// API запрос
}, 500);
input.addEventListener('input', (e) => {
handleSearch(e.target.value);
});
7. Throttle функция (ограничение частоты)
Throttle — выполняет функцию максимум один раз за указанный период.
function throttle(callback, limit) {
let inThrottle = false;
return function(...args) {
if (!inThrottle) {
callback.apply(this, args);
inThrottle = true;
setTimeout(() => {
inThrottle = false;
}, limit);
}
};
}
// Использование
const handleScroll = throttle(() => {
console.log('Скролл срабатывает максимум раз в 1 секунду');
}, 1000);
window.addEventListener('scroll', handleScroll);
8. Callback при загрузке ресурса
const img = new Image();
img.onload = () => {
console.log('Изображение загружено');
};
img.src = 'path/to/image.jpg';
// С задержкой
setTimeout(() => {
console.log('Проверка после загрузки');
}, 2000);
Сравнительная таблица
| Метод | Использование | Особенности |
|---|---|---|
| setTimeout | Одноразовая задержка | Простой и распространённый |
| setInterval | Повторяющаяся задержка | Нужно вручную остановить |
| requestAnimationFrame | Анимации | Синхронизирован с браузером |
| debounce | Отложенное выполнение | Сбрасывается при повторном вызове |
| throttle | Ограничение частоты | Выполняется максимум один раз за период |
Практический пример: Простая анимация загрузки
function showLoadingAnimation() {
const loader = document.querySelector('.loader');
let dots = 0;
const intervalId = setInterval(() => {
dots = (dots + 1) % 4;
loader.textContent = 'Загружаем' + '.'.repeat(dots);
}, 500);
// Остановить через 5 секунд
setTimeout(() => {
clearInterval(intervalId);
loader.textContent = 'Готово!';
}, 5000);
}
showLoadingAnimation();
Отмена задержки
Все таймеры можно отменить:
// Отменить setTimeout
const timeoutId = setTimeout(() => {
console.log('Это не выведется');
}, 5000);
clearTimeout(timeoutId);
// Отменить setInterval
const intervalId = setInterval(() => {
console.log('Интервал');
}, 1000);
clearInterval(intervalId);
Главное отличие от Promise
setTimeout/setInterval — это callback-based подход (старый стиль):
setTimeout(() => {
console.log('Готово');
}, 1000);
Promise — это более современный подход с лучшей обработкой ошибок и цепочкой операций:
new Promise(resolve => {
setTimeout(resolve, 1000);
}).then(() => {
console.log('Готово');
});
Однако setTimeout полностью функционален и часто используется без Promise в современном коде для простых задержек.