> В какой очередности выполняются console.log, setTimeout и Promise в JavaScript (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Точка, EvApps, Сбер

Стек: JavaScript

> Пример ответа

Короткий ответ

Порядок выполнения: сначала синхронный console.log, затем микрозадачи (Promise.then), затем макрозадачи (setTimeout). Это определяется event loop: синхронный код выполняется немедленно, Promise попадает в очередь микрозадач и выполняется до следующей макрозадачи, а setTimeout - в очередь макрозадач и выполняется после всех микрозадач текущего цикла.

Подробное объяснение

Event loop в JavaScript обрабатывает код в строгой последовательности. Сначала выполняется весь синхронный код в текущем стеке вызовов, включая console.log. Когда стек очищается, event loop проверяет очередь микрозадач (microtask queue), куда попадают колбэки Promise (через .then, .catch, .finally) и queueMicrotask. Все микрозадачи выполняются до начала обработки следующей макрозадачи. Макрозадачи (setTimeout, setInterval, I/O) обрабатываются по одной за цикл, после того как очередь микрозадач опустеет.

Таким образом, если у вас есть console.log, Promise и setTimeout в одном синхронном блоке, порядок будет:

  1. console.log (синхронно)
  2. Колбэк Promise (микрозадача)
  3. Колбэк setTimeout (макрозадача)

Promise.resolve() создаёт микрозадачу, которая выполняется раньше любого setTimeout, даже если таймер установлен на 0 мс.

На практике

Это знание критично для отладки асинхронного кода и предотвращения race conditions. Например, при работе с DOM или состоянием приложения важно понимать, что обновление данных в Promise произойдёт до обработки событий таймера. Это также влияет на производительность: если в микрозадачах создавать новые микрозадачи, можно заблокировать event loop, так как макрозадачи не будут выполняться до полной очистки очереди микрозадач.

Пример кода

JAVASCRIPT
console.log('1: синхронный');
setTimeout(() => console.log('4: макрозадача'), 0);
Promise.resolve().then(() => console.log('3: микрозадача'));
console.log('2: синхронный');
// Вывод: 1, 2, 3, 4

Как отвечать на собеседовании

Начни с чёткого порядка: синхронный код → микрозадачи → макрозадачи. Объясни, что event loop обрабатывает микрозадачи до перехода к следующей макрозадаче. Приведи пример с Promise.resolve().then() и setTimeout(0). Упомяни, что async/await - это синтаксический сахар над Promise, поэтому await создаёт микрозадачу. Если спросят про process.nextTick в Node.js - скажи, что он выполняется до других микрозадач.

Что проверяет интервьюер

Интервьюер оценивает понимание event loop, очередей задач и приоритетов выполнения. Важно показать, что ты знаешь разницу между микрозадачами и макрозадачами, а также как это влияет на порядок выполнения кода. Для senior-уровня ожидается умение объяснить, почему так спроектировано (например, для обеспечения предсказуемости UI-обновлений).

Типичные ошибки

  • Утверждение, что setTimeout(0) выполняется сразу после синхронного кода - на самом деле он ждёт все микрозадачи.
  • Путаница между setTimeout и setImmediate в Node.js - порядок зависит от фазы event loop.
  • Игнорирование вложенных микрозадач - они могут отложить макрозадачи на неопределённое время.
  • Предположение, что Promise.resolve() выполняется синхронно - колбэк .then всегда асинхронен.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью