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.
  • Колбэк — функция, переданная для вызова позже; при вложении образует трудночитаемый «ад колбэков».
Проверьте себя
1. Код: console.log('A'); setTimeout(() => console.log('B'), 0); console.log('C'). Порядок вывода?
AA B C
BA C B
CB A C
DC A B
2. Какая функция останавливает периодический таймер setInterval?
AstopInterval
BclearTimeout
CclearInterval
DremoveInterval
3. Что такое callback hell?
AОшибка в колбэке
BГлубокое вложение колбэков, делающее код нечитаемым
CКолбэк без аргументов
DВызов колбэка до готовности данных
Поддержать проект