setTimeout, setInterval и колбэки
setTimeout, setInterval и колбэки — основы асинхронности в JavaScript: как откладывать выполнение кода и запускать его периодически.
Колбэк (callback) — это функция, которую передают другой функции как аргумент, чтобы вызвать позже. Это основная идея асинхронного кода в JS.
setTimeout — отложенный вызов
setTimeout(fn, delay) вызывает функцию fn один раз через delay миллисекунд. Остальной код продолжает выполняться немедленно, не ожидая истечения задержки.
console.log('Начало');
setTimeout(() => {
console.log('Прошло 2 секунды');
}, 2000);
console.log('Конец');
// Выполнится сразу, не дожидаясь таймера
Вывод:
Начало Конец Прошло 2 секунды
Обратите внимание: «Конец» выводится до «Прошло 2 секунды», хотя в коде написано раньше. Это и есть асинхронность — таймер не блокирует поток.
setTimeout возвращает идентификатор таймера. Его можно передать в clearTimeout, чтобы отменить вызов:
const timerId = setTimeout(() => {
console.log('Это не выведется');
}, 3000);
clearTimeout(timerId); // отменяем до истечения
console.log('Таймер отменён');
Вывод:
Таймер отменён
setInterval — периодический вызов
setInterval(fn, delay) вызывает функцию каждые delay миллисекунд, пока его не остановят через clearInterval.
let count = 0;
const intervalId = setInterval(() => {
count++;
console.log('Тик:', count);
if (count === 3) {
clearInterval(intervalId); // останавливаем после 3 тиков
console.log('Стоп!');
}
}, 1000);
Вывод:
Тик: 1 Тик: 2 Тик: 3 Стоп!
Колбэки и «ад колбэков»
Когда одна асинхронная операция зависит от результата другой, колбэки вкладываются друг в друга. Глубокое вложение делает код плохо читаемым — это называют callback hell.
// имитация запросов к серверу с задержкой
function getUser(id, cb) {
setTimeout(() => cb({ id, name: 'Аня' }), 100);
}
function getOrders(userId, cb) {
setTimeout(() => cb([{ item: 'книга' }]), 100);
}
// вложенные колбэки — callback hell
getUser(1, user => {
console.log('Пользователь:', user.name);
getOrders(user.id, orders => {
console.log('Заказы:', orders.length);
// и так далее...
});
});
Вывод:
Пользователь: Аня Заказы: 1
Именно для решения проблемы callback hell появились промисы и
async/await.
Коротко
setTimeout(fn, ms)— вызываетfnодин раз через указанное время, не блокируя поток.setInterval(fn, ms)— повторяет вызов каждыеmsмс; останавливается черезclearInterval.- Колбэк — функция, переданная для вызова позже; при вложении образует трудночитаемый «ад колбэков».