← Назад к вопросам

Куда пойдет результат упавшего Promise?

1.8 Middle🔥 212 комментариев
#JavaScript Core

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI4 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Куда пойдет результат "упавшего" Promise?

В терминологии JavaScript Promise не "падает", а переходит в состояние rejected (отклонён). Когда промис отклоняется, его результат (обычно объект ошибки) должен быть обработан, иначе это приведет к "тихой" ошибке, которая может нарушить работу приложения. Давайте разберем механизм работы отклоненных промисов.

Механизм обработки отклоненных промисов

Промис в JavaScript имеет три состояния: pending (ожидание), fulfilled (выполнено), rejected (отклонено). Когда промис отклоняется, он передает причину отказа (обычно объект Error) по цепочке вызовов.

1. Обработка через .catch()

Самый распространенный способ обработки — метод .catch():

fetch('/api/data')
  .then(response => response.json())
  .catch(error => {
    console.error('Ошибка при получении данных:', error);
    return { fallback: 'default data' };
  });

2. Второй параметр .then()

Можно использовать второй аргумент .then():

fetch('/api/data')
  .then(
    response => response.json(),
    error => console.error('Ошибка сети:', error)
  );

3. Глобальная обработка

Если ошибка не обработана, она попадает в глобальные обработчики:

В браузере:
// Отлавливает необработанные отклонения промисов
window.addEventListener('unhandledrejection', event => {
  console.error('Необработанный промис:', event.reason);
  event.preventDefault(); // Предотвращает вывод в консоль ошибки по умолчанию
});
В Node.js:
process.on('unhandledRejection', (reason, promise) => {
  console.error('Необработанный промис:', reason);
});

Что происходит с необработанным отклоненным промисом?

Если отклоненный промис не обработан, его результат "теряется", но вызывает проблемы:

  1. В браузере:

    • Срабатывает событие unhandledrejection
    • В консоли появляется предупреждение Uncaught (in promise) Error
    • Приложение продолжает работу, но возможны неявные баги
  2. В Node.js (версии < 15):

    • Предупреждение в консоль
    • Приложение продолжает работу
    • В версиях Node.js ≥ 15 необработанные отклонения приводят к завершению процесса!

Практические рекомендации

Всегда обрабатывайте ошибки:

async function loadData() {
  try {
    const response = await fetch('/api/data');
    return await response.json();
  } catch (error) {
    // Явная обработка ошибки
    console.error('Ошибка загрузки:', error);
    throw error; // Пробрасываем дальше при необходимости
  }
}

Используйте Promise.allSettled() для групповой обработки:

const promises = [promise1, promise2, promise3];
const results = await Promise.allSettled(promises);

results.forEach((result, index) => {
  if (result.status === 'rejected') {
    console.error(`Промис ${index} отклонен:`, result.reason);
  }
});

Паттерн "защитного промиса":

function safePromise(promise) {
  return promise
    .then(data => ({ success: true, data }))
    .catch(error => ({ success: false, error }));
}

// Использование
const result = await safePromise(fetch('/api/data'));
if (!result.success) {
  // Обработка ошибки
}

Критические последствия необработанных промисов

  • Утечки памяти: Необработанные промисы могут удерживать ресурсы
  • Непредсказуемое поведение: Логика приложения может сломаться в неожиданных местах
  • Сложность отладки: Ошибки без стека вызовов трудно диагностировать

Вывод: Результат отклоненного промиса должен быть явно обработан через .catch(), try/catch с async/await или глобальные обработчики. Современные линтеры (ESLint с правилом no-floating-promises) помогают выявлять необработанные промисы на этапе разработки. Всегда предусматривайте обработку ошибок для каждого промиса в вашем коде — это основа надежных асинхронных операций в JavaScript.

Куда пойдет результат упавшего Promise? | PrepBro