> Как перехватывать ошибки в промисах и чем это отличается от try-catch (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Kaspersky
Стек: JavaScript
> Пример ответа
Короткий ответ
Перехват ошибок в промисах осуществляется через метод .catch() или второй колбэк в .then(). Основное отличие от try-catch в том, что .catch() работает асинхронно и перехватывает rejections на любом этапе цепочки промисов, тогда как try-catch синхронен и не ловит ошибки внутри асинхронных операций без await. Для асинхронного кода с async/await try-catch становится эквивалентом .catch().
Подробное объяснение
Промисы предоставляют встроенный механизм обработки ошибок через .catch(), который автоматически перехватывает rejections и исключения, возникшие в предыдущих .then(). Это позволяет строить цепочки с единой точкой обработки ошибок. try-catch в синхронном коде работает только с синхронными исключениями - он не может перехватить rejection промиса, если не используется await. При использовании async/await try-catch становится синтаксическим сахаром над .catch(), но с важным нюансом: await может выбросить только rejected промис, а не синхронное исключение внутри промиса (оно превращается в rejection автоматически).
Ключевое различие - в propagation: .catch() в цепочке промисов может быть расположен после нескольких .then(), перехватывая ошибки из любого предыдущего звена. try-catch же работает только в рамках одного блока. Также .catch() возвращает новый промис, позволяя продолжить цепочку после обработки ошибки, что невозможно в try-catch без дополнительных конструкций.
На практике
В современном коде с async/await предпочтительнее использовать try-catch для читаемости, но .catch() остаётся актуальным для:
- обработки ошибок в цепочках без
await - случаев, когда нужно перехватить ошибку и продолжить цепочку (recover)
- работы с Promise.all, Promise.race и другими комбинаторами
Важно помнить, что если в .catch() выбросить новое исключение или вернуть rejected промис, ошибка пойдёт дальше по цепочке. В try-catch для аналогичного поведения нужно использовать throw внутри catch-блока.
Пример кода
JAVASCRIPT// Синхронный try-catch не ловит асинхронные ошибкиtry {Promise.reject('ошибка');} catch (e) {// Этот блок не выполнится}// Правильно: .catch()Promise.reject('ошибка').catch(err => console.log(err)); // 'ошибка'// async/await эквивалентasync function handleError() {try {await Promise.reject('ошибка');} catch (err) {console.log(err); // 'ошибка'}}// Восстановление после ошибки через .catch()fetch('/api/data').then(response => response.json()).catch(() => ({ data: 'default' })) // возвращаем fallback.then(data => console.log(data));
Как отвечать на собеседовании
Начни с ключевого отличия - синхронность vs асинхронность. Подчеркни, что .catch() работает на уровне промисов, а try-catch - на уровне синхронного кода. Упомяни, что с async/await различие стирается, но .catch() даёт больше гибкости в цепочках. Приведи пример, где try-catch не сработает без await. Покажи понимание propagation и recovery. Избегай излишней теории - сфокусируйся на практических сценариях.
Что проверяет интервьюер
- понимание асинхронной природы JavaScript
- знание механизма rejection propagation в промисах
- умение различать синхронные и асинхронные ошибки
- способность выбрать правильный инструмент под задачу
- знание тонкостей
async/awaitи его связи с промисами
Типичные ошибки
- попытка использовать
try-catchбезawaitдля ловли rejections - забывание, что
.catch()возвращает новый промис, и попытка продолжить цепочку после него без return - путаница между синхронным throw и асинхронным rejection
- игнорирование того, что ошибка в
.catch()может быть перехвачена следующим.catch()в цепочке - предположение, что
try-catchвasyncфункции ловит все ошибки (он не ловит ошибки из других асинхронных операций безawait)
> Похожие задачи по frontend
Что такое Jest
Как в цикле for-in в JavaScript вывести только собственные ключи объекта без ключей прототипа
Как называется подход, когда обработчик клика вешается на контейнер, а событие обрабатывается на дочерних элементах
Что такое функция обратного вызова (callback) и когда она вызывается в JavaScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью