← Назад к вопросам

В какой момент callback из setTimeout попадает в Event Loop

2.2 Middle🔥 241 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

В какой момент callback из setTimeout попадает в Event Loop

Понимание Event Loop

Event Loop — это механизм, который позволяет JavaScript (однопоточному языку) выполнять асинхронные операции. Он постоянно проверяет, есть ли задачи для выполнения, и распределяет их на выполнение между стеком вызовов и различными очередями.

Порядок попадания setTimeout в Event Loop

Когда вы вызываете setTimeout(), callback не сразу попадает в Event Loop. Происходит следующее:

  1. Регистрация в Web APIsetTimeout() передаёт ваш callback в Web API (таймер браузера или Node.js)
  2. Ожидание времени — Web API ждёт указанное время (в миллисекундах)
  3. Попадание в Queue — когда время истекло, callback попадает в Callback Queue (макротаска)
  4. Проверка Event Loop — Event Loop видит, что Call Stack пуст, и берёт callback из очереди
  5. Выполнение — callback выполняется в основном потоке

Пример с временной шкалой

console.log("1. Start");

setTimeout(() => {
  console.log("3. setTimeout callback");
}, 100);

Promise.resolve().then(() => {
  console.log("2. Promise callback");
});

console.log("4. End");

Вывод:

1. Start
4. End
2. Promise callback
3. setTimeout callback

Почему такой порядок?

  • Синхронный код (1, 4) выполняется сразу
  • Promise (Microtask) выполняется перед Macrotask (setTimeout)
  • setTimeout (100ms) попадает в Event Loop только после истечения времени и пустого Call Stack

Микротаски vs Макротаски

Микротаски (Microtask Queue) — выше приоритет:

  • Promise (then, catch, finally)
  • MutationObserver
  • queueMicrotask()

Макротаски (Macrotask Queue / Callback Queue) — ниже приоритет:

  • setTimeout
  • setInterval
  • setImmediate (Node.js)
  • I/O операции
  • UI события

Ключевой момент: "0" в setTimeout

setTimeout(() => {
  console.log("Выполнится не сразу");
}, 0);

Даже с задержкой 0, callback не выполнится сразу. Он попадёт в Callback Queue и будет выполнен:

  • После текущего синхронного кода
  • После всех микротасок
  • После отрисовки (если нужна)

Визуализация Event Loop

// Call Stack пуст?
// Нет → Выполняй синхронный код
// Да ↓
// Есть микротаски?
// Да → Выполняй все микротаски
// Нет ↓
// Отрисовать UI?
// Да → Отрисуй
// Нет ↓
// Есть макротаски?
// Да → Выполняй одну макротаску → Повторяй цикл
// Нет → Ждёшь

Практический пример

console.log("Start");

setTimeout(() => {
  console.log("setTimeout 0");
}, 0);

Promise.resolve()
  .then(() => {
    console.log("Promise 1");
  })
  .then(() => {
    console.log("Promise 2");
  });

console.log("End");

Вывод:

Start
End
Promise 1
Promise 2
setTimeout 0

Этот пример демонстрирует, что callback из setTimeout попадает в Event Loop только после выполнения всех синхронных операций и всех микротасок.

Заключение

Callback из setTimeout попадает в Event Loop не в момент вызова функции, а в момент, когда:

  1. Истекло время ожидания (или 0ms, но это всё равно асинхронно)
  2. Web API передаёт callback в Callback Queue
  3. Event Loop проверяет Call Stack и видит, что он пуст
  4. Event Loop берёт callback из Callback Queue и выполняет его

Это ключевое понимание помогает избежать проблем с асинхронным кодом и правильно предсказывать порядок выполнения операций.

В какой момент callback из setTimeout попадает в Event Loop | PrepBro