> Попадем ли в catch при ошибке в асинхронном вызове внутри try в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Kaspersky
Стек: JavaScript
> Пример ответа
Короткий ответ
Нет, не всегда. try/catch ловит только синхронные ошибки и ошибки в await-выражениях. Если асинхронный вызов запущен без await (например, somePromise.catch() или setTimeout), ошибка не попадёт в catch - она станет unhandled rejection. Для надёжной обработки используйте await внутри try или цепочку .catch().
Подробное объяснение
Механика try/catch в JavaScript привязана к синхронному стеку вызовов. Когда вы пишете:
JAVASCRIPTtry {asyncFunction(); // без await} catch (e) {// сюда не попадём}
asyncFunction() возвращает Promise, но сам вызов завершается синхронно. Ошибка внутри асинхронной части возникнет позже, когда стек try уже завершился. Поэтому catch не сработает.
Правильный вариант - await:
JAVASCRIPTtry {await asyncFunction();} catch (e) {// сюда попадём, если asyncFunction вернёт rejected promise}
await приостанавливает выполнение и передаёт управление в catch при rejection. Это работает и в async функциях, и в top-level await (в модулях).
Исключение - синхронная ошибка внутри самого async-функции до первого await. Она тоже превращается в rejected promise, поэтому await её поймает.
На практике
- В
asyncфункциях всегда используйтеtry/catchсawait, а не с голым вызовом. - Для параллельных операций (
Promise.all,Promise.allSettled) оборачивайте весь вызов вtry/catch- rejection любого из промисов попадёт вcatch. - Если нужно обработать ошибку без
await(например, в обработчике события), используйте.catch()на промисe. - Для
setTimeout,setInterval, колбэков из event listeners -try/catchвнутри колбэка не спасёт, если ошибка происходит асинхронно. Нужен собственныйtry/catchвнутри самого колбэка.
Пример кода
JAVASCRIPT// ❌ Ошибка не будет пойманаtry {fetch('/api/data');} catch (e) {console.log('Не сработает');}// ✅ Правильно с awaitasync function load() {try {const response = await fetch('/api/data');const data = await response.json();return data;} catch (e) {console.log('Поймали:', e.message);}}// ✅ Альтернатива без awaitfetch('/api/data').then(r => r.json()).catch(e => console.log('Поймали:', e.message));// ⚠️ Promise.all - тоже ловитсяtry {await Promise.all([fetch('/a'), fetch('/b')]);} catch (e) {// сработает при rejection любого}
Как отвечать на собеседовании
Начните с прямого ответа: "Нет, если вызов не обёрнут в await". Затем объясните разницу между синхронной ошибкой и rejection промиса. Приведите пример с await и без. Упомяните, что async функция всегда возвращает Promise, поэтому даже синхронная ошибка внутри неё становится rejection. Если спросят про Promise.all - скажите, что try/catch ловит rejection любого из промисов.
Что проверяет интервьюер
- Понимание event loop и асинхронности.
- Знание разницы между
throwи rejected promise. - Умение работать с
async/awaitи.catch(). - Понимание, что
try/catch- синхронная конструкция.
Типичные ошибки
- Ожидание, что
try/catchпоймает ошибку изsetTimeoutили колбэка. - Забывание
awaitперед асинхронным вызовом внутриtry. - Попытка использовать
try/catchвокругPromiseбезawaitвasyncфункции. - Непонимание, что ошибка в
.then()без.catch()тоже станет unhandled rejection.
> Похожие задачи по frontend
Как определить, что элемент находится в viewport в JavaScript
В чем разница XML и JSON
Создавал ли ты кастомные события мыши во frontend
Что такое типизация в JavaScript?
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью