> В каком порядке выполняются промисы и их обработчики then/catch в JavaScript и как это влияет на порядок ошибок? (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Яндекс
Стек: JavaScript
> Пример ответа
Промисы и их обработчики then/catch выполняются в порядке, определённом микрозадачами (microtasks) в цикле событий (event loop). Когда промис переходит в состояние resolved или rejected, его обработчики не выполняются сразу, а ставятся в очередь микрозадач. После завершения текущего синхронного кода и макрозадачи (например, setTimeout), движок обрабатывает всю очередь микрозадач перед следующим рендерингом или макрозадачей.
Порядок выполнения:
- Если промис уже разрешён (например,
Promise.resolve()), тоthenдобавляется в очередь микрозадач и выполняется после синхронного кода. - Цепочка
then/catchвыполняется последовательно: каждый следующий обработчик ждёт завершения предыдущего, даже если он возвращает другой промис (в этом случае новый промис добавляет свои обработчики в очередь). - Ошибки обрабатываются в порядке цепочки: если в
thenвозникает исключение или возвращается отклонённый промис, управление передаётся ближайшемуcatchв цепочке. Еслиcatchнет, ошибка становится необработанной (unhandled rejection).
Пример:
JAVASCRIPTPromise.resolve().then(() => { throw new Error('Ошибка 1'); }).then(() => console.log('Это не выполнится')).catch(err => console.log(err.message)) // "Ошибка 1".then(() => console.log('После catch'));
Здесь ошибка перехватывается catch, и цепочка продолжается. Если бы catch был пропущен, ошибка всплыла бы до глобального обработчика.
Влияние на порядок ошибок: ошибки обрабатываются строго по цепочке, и только первый catch после места возникновения ошибки её перехватывает. Если ошибка возникает в catch (например, новый throw), она передаётся следующему обработчику вниз по цепочке. Это позволяет строить гибкие сценарии восстановления, но требует внимания к порядку, чтобы не потерять исключения.
> Похожие задачи по frontend
Почему нельзя использовать forEach для реализации some с прерыванием?
Как обработать успешное разрешение одного из промисов в функции any?
Как определить момент завершения всех промисов с ошибками для вызова reject в JavaScript?
Почему нельзя просто вернуть Promise.resolve с промисом внутри в реализации any?
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью