Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

Документы

Медиа

Назад
Вопрос про JavaScript: try catch, setTimeout, event loop, asynchronous error handling, call stack

Почему try/catch не ловит ошибки внутри setTimeout?

Этот вопрос проверяет понимание асинхронной природы JavaScript и того, как механизм try/catch взаимодействует с циклом событий.

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

Конструкция try/catch работает синхронно и ловит ошибки только в текущем блоке выполнения. Функция, переданная в setTimeout, выполняется позже, в другом цикле событий, когда контекст try/catch уже завершён. Поэтому ошибка возникает вне зоны видимости блока catch. Для обработки таких ошибок нужно помещать try/catch внутрь самой асинхронной функции или использовать другие механизмы, например, обработчики событий 'unhandledrejection' для промисов.

Длинный ответ

Конструкция try/catch в JavaScript предназначена для синхронной обработки ошибок. Она работает в рамках текущего синхронного потока выполнения, захватывая исключения, которые возникают непосредственно внутри блока try в тот же самый "тик" цикла событий.

Как работает setTimeout и цикл событий

Функция setTimeout является асинхронной. Она не выполняет переданный колбэк немедленно, а планирует его выполнение на будущее. После истечения указанной задержки колбэк помещается в очередь задач (task queue). Цикл событий (event loop) заберёт его оттуда и выполнит только тогда, когда основной стек вызовов (call stack) будет пуст. Это происходит уже после того, как весь синхронный код, включая блок try/catch, завершил свою работу.

Почему ошибка не ловится

Рассмотрим пример:

try {
  setTimeout(() => {
    throw new Error('Ошибка внутри таймаута!');
  }, 1000);
} catch (error) {
  // Этот блок НЕ выполнится
  console.log('Ошибка поймана:', error);
}

Здесь setTimeout вызывается синхронно и завершается успешно (он просто планирует задачу). Сам колбэк с throw выполнится асинхронно, через секунду, в совершенно новом контексте выполнения. К этому моменту управление уже давно вышло из блока try, поэтому поймать эту ошибку стандартным catch невозможно.

Как правильно обрабатывать асинхронные ошибки

  • Поместить try/catch внутрь асинхронной функции:
setTimeout(() => {
  try {
    throw new Error('Теперь поймается!');
  } catch (error) {
    console.log('Ошибка поймана внутри:', error.message);
  }
}, 1000);
  • Использовать Промисы с .catch():
new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(new Error('Ошибка в промисе'));
  }, 1000);
}).catch(error => {
  console.log('Поймано через catch промиса:', error.message);
});
  • Для глобального перехвата необработанных ошибок можно использовать window.onerror (в браузере) или process.on('uncaughtException') (в Node.js).

Вывод: Используйте try/catch только для синхронного кода. Для обработки ошибок в асинхронных операциях (таймауты, промисы, события) применяйте соответствующие асинхронные механизмы — обработчики .catch() у промисов или оборачивайте опасный код в try/catch непосредственно внутри асинхронного колбэка.

Уровень

  • Рейтинг:

    4

  • Сложность:

    3

Навыки

  • JavaScript

    JavaScript

Ключевые слова

#try catch

#setTimeout

#event loop

#asynchronous error handling

#call stack

Подпишись на React Developer в телеграм