Обработка ошибок в отдельных промисах с Promise.all
Быстрый ответ
Для обработки нескольких промисов одновременно и для возможности обработать как успешные, так и ошибочные события используйте метод Promise.allSettled
. Этот метод возвращает массив объектов с указанием их состояния: { status: 'fulfilled', value: ... }
для завершенных успешно и { status: 'rejected', reason: ... }
для отклонённых промисов. Проход по результатам позволяет приспособиться к каждому событию.
Promise.allSettled([promise1, promise2, promise3]).then((results) => {
results.forEach(({ status, value, reason }) => {
if (status === 'fulfilled') {
console.log('Успех:', value);
} else {
console.error('Ошибка:', reason);
}
});
});
Метод Promise.allSettled
значительно упрощает одновременную обработку результатов выполнения промисов, независимо от их исхода.
Подробное рассмотрение и распространенные ошибки
Стоит помнить, что Promise.all
отклоняется сразу же, как только возникает ошибка в любом из промисов, что может привести к прерыванию цепочки. Чтобы этого избежать, рекомендуется добавить метод catch
к каждому промису в массиве:
// Функция для перехвата ошибок
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);
}
});
});
Ни один промис не останется без внимания
Для предотвращения смешивания промисов и обычных значений в одном массиве, рекомендуется оборачивать все элементы в промисы:
const ensurePromise = (item) => Promise.resolve(item).catch(e => e);
const mixedArray = [value1, promise1, value2].map(ensurePromise);
Promise.allSettled(mixedArray).then(resultsHandlingFunction);
Пришло время вскрыть "подарки"
Применение Promise.allSettled()
дает возможность провести детальный анализ результатов выполнения промисов:
Promise.allSettled(promises)
.then((results) => results.map(result => {
if (result.status === 'fulfilled') {
return result.value;
} else {
return handleErrorFlipAndReverseIt(result.reason);
}
}));
Обратная совместимость – это важно
В окружениях, где нет поддержки Promise.allSettled
, можно использовать полифилы или специализированные библиотеки:
if (!Promise.allSettled) {
Promise.allSettled = promises => Promise.all(promises.map(p => p.then(
value => ({ status: 'fulfilled', value }),
reason => ({ status: 'rejected', reason })
)));
}
Визуализация
Работа с Promise.all
аналогична конвейеру по обработке посылок:
Промис | Результат | Обработка |
---|---|---|
📦 (Успех) | ✅ | Доставка |
📦 (Успех) | ✅ | Доставка |
📦 (Ошибка) | ❌ | Обработка ошибок |
📦 (Успех) | ✅ | Доставка |
📦 (Ошибка) | ❌ | Обработка ошибок |
Promise.allSettled(promises).then(results => {
const successfulDeliveries = results.filter(r => r.status === 'fulfilled');
const errorsToHandle = results.filter(r => r.status === 'rejected');
});
Убедитесь, что каждый исход обработан соответствующим образом.
Управление ошибками профессионально
Для углубленной обработки ошибок пройдите по результатам и отобразите информацию о каждой ошибке:
Promise.allSettled(promises).then(results => {
results.forEach((result, index) => {
if (result.status === 'rejected') {
console.error(`Ошибка в промисе номер ${index + 1}:`, result.reason);
}
});
});
Будьте внимательны и избегайте трудностей
- Завершайте каждый блок
then()
сcatch()
. - Не забывайте возвращать промисы.
- Оставляйте под контролем ошибки.