> Как catch влияет на цепочку промисов в JavaScript (JavaScript)

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

Компании: Альфа-банк

Стек: JavaScript

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

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

catch в цепочке промисов перехватывает reject из любого предшествующего then или самого промиса, после чего возвращает новый resolved промис, если в catch не выброшено исключение или не возвращён reject. Это позволяет восстанавливать цепочку после ошибки. Если catch расположен в середине цепочки, он "проглатывает" ошибку, и последующие then выполняются нормально. Без catch ошибка распространяется до конца цепочки и вызывает unhandled rejection.

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

Цепочка промисов строится на том, что каждый then и catch возвращает новый промис. Когда промис переходит в состояние rejected, управление передаётся ближайшему catch в цепочке. Если catch отработал без ошибок, он возвращает resolved промис со значением, которое он вернул (или undefined). Это значение передаётся в следующий then.

Важный нюанс: catch не прерывает цепочку, а восстанавливает её. После catch можно продолжать then. Если в catch выбросить новую ошибку или вернуть rejected промис, цепочка снова перейдёт в состояние ошибки и будет искать следующий catch.

Порядок catch в цепочке имеет значение: catch перехватывает ошибки только от промисов, расположенных выше по цепочке. Если ошибка возникла после catch (в then, который идёт после catch), её нужно обрабатывать отдельным catch ниже.

Также catch может быть расположен в конце цепочки как глобальный обработчик ошибок. В этом случае он перехватит любую необработанную ошибку из всей цепочки.

На практике

На практике catch используют для:

  • обработки ошибок API-запросов с восстановлением (например, возврат fallback данных)
  • логирования ошибок без прерывания цепочки
  • централизованной обработки ошибок в конце цепочки
  • преобразования одной ошибки в другую (re-throw с новым сообщением)

Важно помнить, что catch сам может стать источником ошибки, если внутри него происходит исключение. Это может привести к неожиданному поведению, если не предусмотреть обработку.

Пример кода

JAVASCRIPT
fetch('/api/data')
.then(response => response.json())
.then(data => {
// обработка данных
return data;
})
.catch(error => {
// перехватываем ошибку от fetch или первого then
console.error('Ошибка запроса:', error);
return { fallback: true }; // восстанавливаем цепочку
})
.then(result => {
// этот then выполнится всегда: либо с данными, либо с fallback
console.log(result);
});

Если в последнем then возникнет ошибка, она не будет обработана - нужно добавить ещё один catch в конец.

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

Начни с того, что catch перехватывает reject и возвращает resolved промис. Объясни, что это позволяет восстанавливать цепочку. Приведи пример с восстановлением после ошибки. Упомяни, что catch не прерывает цепочку, а только обрабатывает ошибку. Подчеркни разницу между catch в середине и в конце цепочки. Если спросят про unhandled rejection - объясни, что это ошибка, которая не была перехвачена ни одним catch.

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

Интервьюер проверяет понимание того, как работает propagation ошибок в промисах, различие между catch как обработчиком и catch как восстановителем цепочки, а также умение предсказывать поведение цепочки с несколькими then и catch. Также проверяется знание того, что catch возвращает промис, и что после catch цепочка продолжается.

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

  • Думать, что catch прерывает цепочку навсегда - на самом деле после catch можно продолжать then.
  • Забывать, что catch сам может выбросить ошибку, и это нужно обрабатывать.
  • Располагать catch в начале цепочки, думая, что он перехватит ошибки из всех последующих then - на самом деле он перехватывает только ошибки из промисов выше по цепочке.
  • Не добавлять catch в конец цепочки, что приводит к unhandled rejection при ошибке в последнем then.

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

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