Обработка ошибок в отдельных промисах с Promise.all

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для обработки нескольких промисов одновременно и для возможности обработать как успешные, так и ошибочные события используйте метод Promise.allSettled. Этот метод возвращает массив объектов с указанием их состояния: { status: 'fulfilled', value: ... } для завершенных успешно и { status: 'rejected', reason: ... } для отклонённых промисов. Проход по результатам позволяет приспособиться к каждому событию.

JS
Скопировать код
Promise.allSettled([promise1, promise2, promise3]).then((results) => {
  results.forEach(({ status, value, reason }) => {
    if (status === 'fulfilled') {
      console.log('Успех:', value);
    } else {
      console.error('Ошибка:', reason);
    }
  });
});

Метод Promise.allSettled значительно упрощает одновременную обработку результатов выполнения промисов, независимо от их исхода.

Кинга Идем в IT: пошаговый план для смены профессии

Подробное рассмотрение и распространенные ошибки

Стоит помнить, что Promise.all отклоняется сразу же, как только возникает ошибка в любом из промисов, что может привести к прерыванию цепочки. Чтобы этого избежать, рекомендуется добавить метод catch к каждому промису в массиве:

JS
Скопировать код
// Функция для перехвата ошибок
const withCatch = (promise) => promise.catch(e => ({ error: e }));

// Эти обработчики заботятся о ошибках
const promises = [promise1, promise2, promise3].map(withCatch);

Promise.all(promises).then(results => {
  results.forEach(result => {
    if (result.error) {
      console.error('Обработана ошибка:', result.error);
    } else {
      console.log('Успех:', result);
    }
  });
});

Ни один промис не останется без внимания

Для предотвращения смешивания промисов и обычных значений в одном массиве, рекомендуется оборачивать все элементы в промисы:

JS
Скопировать код
const ensurePromise = (item) => Promise.resolve(item).catch(e => e);

const mixedArray = [value1, promise1, value2].map(ensurePromise);

Promise.allSettled(mixedArray).then(resultsHandlingFunction);

Пришло время вскрыть "подарки"

Применение Promise.allSettled() дает возможность провести детальный анализ результатов выполнения промисов:

JS
Скопировать код
Promise.allSettled(promises)
  .then((results) => results.map(result => {
    if (result.status === 'fulfilled') {
      return result.value;
    } else {
      return handleErrorFlipAndReverseIt(result.reason);
    }
  }));

Обратная совместимость – это важно

В окружениях, где нет поддержки Promise.allSettled, можно использовать полифилы или специализированные библиотеки:

JS
Скопировать код
if (!Promise.allSettled) {
  Promise.allSettled = promises => Promise.all(promises.map(p => p.then(
    value => ({ status: 'fulfilled', value }),
    reason => ({ status: 'rejected', reason })
  )));
}

Визуализация

Работа с Promise.all аналогична конвейеру по обработке посылок:

ПромисРезультатОбработка
📦 (Успех)Доставка
📦 (Успех)Доставка
📦 (Ошибка)Обработка ошибок
📦 (Успех)Доставка
📦 (Ошибка)Обработка ошибок
JS
Скопировать код
Promise.allSettled(promises).then(results => {
  const successfulDeliveries = results.filter(r => r.status === 'fulfilled');
  const errorsToHandle = results.filter(r => r.status === 'rejected');
});

Убедитесь, что каждый исход обработан соответствующим образом.

Управление ошибками профессионально

Для углубленной обработки ошибок пройдите по результатам и отобразите информацию о каждой ошибке:

JS
Скопировать код
Promise.allSettled(promises).then(results => {
  results.forEach((result, index) => {
    if (result.status === 'rejected') {
      console.error(`Ошибка в промисе номер ${index + 1}:`, result.reason);
    }
  });
});

Будьте внимательны и избегайте трудностей

  • Завершайте каждый блок then() с catch().
  • Не забывайте возвращать промисы.
  • Оставляйте под контролем ошибки.

Полезные материалы

  1. Promise.all() – JavaScript | MDN
  2. Promise API – JavaScript.info
  3. Как преобразовать существующий API c обратными вызовами в промисы? – Stack Overflow
  4. Понимание промисов в JavaScript | DigitalOcean