JS Async

Callback-функции и setTimeout

Понять, что callback — это функция, переданная другой функции для вызова позже, и как setTimeout планирует выполнение.

Средний (Intermediate)

Кратко

Callback — функция, которую передают другой функции как аргумент. Она вызывается позже, когда «пришло время». setTimeout(callback, delay) планирует вызов callback через delay миллисекунд. callback не блокирует выполнение — он просто ждёт в очереди.


Подробно

Что такое callback?

Callback — это функция, переданная как аргумент другой функции. Она будет вызвана «обратно» (callback) позже.

function doSomething(callback) { console.log('Делаю...'); callback(); // вызываем callback }

doSomething(() => console.log('Готово!')); // Вывод: Делаю... → Готово!

setTimeout:

setTimeout(() => { console.log('Через 2 секунды'); }, 2000);

setTimeout НЕ «останавливает» JavaScript. Он:

  • Регистрирует callback в таймере
  • Продолжает выполнять следующий код
  • Когда время приходит — callback добавляется в очередь
  • Когда стек пуст — callback выполняется

Порядок выполнения: console.log('1'); setTimeout(() => console.log('2'), 0); console.log('3'); // Вывод: 1, 3, 2

setTimeout(fn, 0) НЕ означает «выполнить немедленно». Это значит: «выполни, когда стек будет пуст».

Почему callback-и существуют:

  • Таймеры (setTimeout, setInterval)
  • События (addEventListener)
  • Сетевые запросы (fetch)
  • Файловые операции

Везде, где результат приходит не сразу — используется callback.


Ментальная модель

Callback — как записка «когда будешь свободен, сделай это». Вы передаёте записку (callback) и идёте дальше. Когда освобождаетесь — читаете записку и выполняете.


Примеры

**Самый простой:**

javascript
function greet(name, callback) {
  console.log(`Привет, ${name}!`);
  callback();
}

greet('Анна', () => console.log('До свидания!'));
// Вывод: Привет, Анна! → До свидания!

Callback вызывается после основной логики.

**Простой:**

javascript
console.log('Начало');

setTimeout(() => {
  console.log('Таймер сработал');
}, 1000);

console.log('Конец');
// Вывод: Начало → Конец → (через 1 сек) Таймер сработал

setTimeout не блокирует: сначала выполняется весь синхронный код.

**Реальный пример:**

javascript
function loadUser(userId, onSuccess, onError) {
  // Имитация сетевого запроса
  setTimeout(() => {
    if (userId > 0) {
      onSuccess({ id: userId, name: 'Анна' });
    } else {
      onError('Неверный ID');
    }
  }, 500);
}

loadUser(
  1,
  (user) => console.log(`Загружен: ${user.name}`),
  (error) => console.log(`Ошибка: ${error}`)
);

Два callback: onSuccess для успеха, onError для ошибки.


Частые ошибки

**Неправильно:** Думать, что setTimeout(fn, 0) выполняется немедленно

**Почему:** setTimeout(fn, 0) планирует callback на следующий тик event loop, после завершения текущего синхронного кода.

**Правильно:** setTimeout(fn, 0) = «выполни, когда стек пуст».

**Неправильно:** Вызывать callback немедленно вместо передачи

**Почему:** doSomething(greet()) — вызов greet() немедленно, результат передаётся. doSomething(greet) — передаётся сама функция.

**Правильно:** Передавайте функцию без скобок: doSomething(greet).

**Неправильно:** Забывать, что callback — это просто функция

**Почему:** Callback не магия. Это обычный аргумент-функция.

**Правильно:** Callback = функция как аргумент. Ничего особенного.


Важно запомнить

  • Callback — функция, переданная как аргумент
  • setTimeout планирует вызов, но не блокирует
  • setTimeout(fn, 0) ≠ немедленное выполнение
  • Порядок: синхронный код → callback'и
  • Callback — основа для таймеров, событий, запросов

Связь

Назад: Вы понимаете стек вызовов и блокировку (JA1) — теперь вы видите, как асинхронность её обходит.

Вперёд: Следующий урок (JA3) — таймеры: setTimeout и setInterval подробнее.

Материалы курса JS Async — PROlab Academy.