> Куда пойдет выполнение после запуска промиса в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Black Wall Group (BWG)
Стек: JavaScript
> Пример ответа
Короткий ответ
После запуска промиса выполнение не блокируется: код продолжает синхронно выполняться дальше, а колбэк .then()/.catch()/.finally() попадает в microtask queue и будет вызван после завершения текущего макрозадачи (macrotask) и очистки стека вызовов. Сам промис переходит в состояние pending, а затем, после разрешения, его обработчики ставятся в очередь микрозадач.
Подробное объяснение
Промис - это объект, представляющий асинхронную операцию. При создании new Promise(executor) функция executor выполняется синхронно - это важно. Внутри executor вызывается resolve() или reject(), что переводит промис в соответствующее состояние (fulfilled/rejected). Однако обработчики .then(), .catch() и .finally(), привязанные к этому промису, не вызываются немедленно. Они помещаются в microtask queue (очередь микрозадач) и будут выполнены только после того, как текущий синхронный код завершится и стек вызовов опустеет.
Механизм event loop работает так:
- Выполняется текущая макрозадача (macrotask) - например, скрипт, обработчик клика, setTimeout.
- После её завершения проверяется очередь микрозадач. Все накопившиеся микрозадачи выполняются по очереди, пока очередь не опустеет.
- Затем браузер может обновить рендеринг (если нужно).
- Извлекается следующая макрозадача.
Таким образом, после запуска промиса (вызова resolve() внутри executor) код продолжает выполняться синхронно, а .then() сработает только после завершения всего синхронного кода в текущей макрозадаче.
На практике
- Если внутри промиса есть
resolve()в конце синхронного кода, обработчик.then()всё равно выполнится асинхронно, после текущего стека. - Если промис создаётся, но его executor содержит
setTimeout, тоresolve()будет вызван позже, и.then()сработает после таймера. - Важно не путать microtask (промисы, MutationObserver) с macrotask (setTimeout, setInterval, I/O). Промисы имеют приоритет перед таймерами.
- При цепочке
.then()каждый следующий обработчик тоже становится микрозадачей и выполняется после предыдущего, но до следующей макрозадачи.
Пример кода
JAVASCRIPTconsole.log('1: синхронный код');const promise = new Promise((resolve) => {console.log('2: executor выполняется синхронно');resolve('3: промис разрешён');});promise.then((value) => {console.log(value); // выведется после '4'});console.log('4: ещё синхронный код');// Вывод:// 1: синхронный код// 2: executor выполняется синхронно// 4: ещё синхронный код// 3: промис разрешён
Как отвечать на собеседовании
Начни с ключевого факта: executor промиса выполняется синхронно, а .then() - асинхронно, через microtask queue. Объясни порядок event loop: сначала стек, потом microtask, потом macrotask. Приведи простой пример с выводом в консоль, чтобы показать разницу. Упомяни, что это поведение стандартизировано в спецификации ECMAScript (Job и PromiseReactionJob). Если собеседник спросит про отличие от setTimeout(fn, 0), объясни, что microtask имеют приоритет перед macrotask.
Что проверяет интервьюер
- Понимание event loop и очередей (microtask vs macrotask).
- Знание, что executor промиса синхронен.
- Умение предсказать порядок выполнения кода с промисами.
- Осознание разницы между асинхронностью промиса и таймеров.
- Глубина: знание спецификации (PromiseJobs, HostEnqueuePromiseJob).
Типичные ошибки
- Утверждение, что
.then()выполняется сразу послеresolve()- это неверно, он всегда асинхронен. - Путаница между microtask и macrotask: думают, что
.then()иsetTimeoutравнозначны по приоритету. - Игнорирование синхронности executor: считают, что весь код внутри промиса асинхронен.
- Непонимание, что вложенные промисы (chain) создают новые микрозадачи, а не выполняются в одном тике.
> Похожие задачи по frontend
Как реализовать функцию, принимающую селектор и возвращающую объект с методами для добавления классов и навешивания событий
Какие новые возможности JavaScript знаешь
Какие коллекции кроме Set существуют в JavaScript
Какие данные (примитивы или объекты) можно хранить в localStorage
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью