Работа с асинхронным кодом в JavaScript и TypeScript часто связана с необходимостью обработки множества промисов. Иногда нам нужно не только дождаться выполнения всех промисов, но и разделить их результаты на успешные и отклонённые. В этом случае на помощь приходит метод Promise.allSettled
, который возвращает статусы всех переданных промисов: fulfilled
(успешно выполненные) или rejected
(отклонённые).
В этой заметке мы рассмотрим, как с помощью типов TypeScript и предикатов (type predicates
) можно упростить обработку результатов Promise.allSettled
, выделяя значения успешных промисов и причины ошибок. Такой подход делает код более читаемым, безопасным и удобным для поддержки.
// Проверяет, является ли результат промиса отклонённым (rejected).
const isPromiseRejected = (input: PromiseSettledResult<unknown>): input is PromiseRejectedResult => input.status === 'rejected';
// Проверяет, является ли результат промиса выполненным (fulfilled).
const isPromiseFulfilled = <T>(input: PromiseSettledResult<T>): input is PromiseFulfilledResult<T> => input.status === 'fulfilled';
// Определяем асинхронную функцию, которая завершится успешно или с ошибкой в зависимости от аргумента.
const testPromise = async (shouldResolve: boolean) => {
if (shouldResolve) return Promise.resolve("🎉 Success promise!"); // Успешное выполнение
return Promise.reject("💢 Error promise!") // Завершение с ошибкой
};
async function run() {
// Ожидаем выполнения всех промисов и обрабатываем результаты с помощью Promise.allSettled.
const data = await Promise.allSettled([
testPromise(true),
testPromise(false), // Завершится с ошибкой
testPromise(true),
]);
// Находим первый выполненный промис и извлекаем его значение.
const response = data.find(isPromiseFulfilled)?.value;
console.log("Ответ успешного промиса:", response);
// Находим первый отклонённый промис и извлекаем причину ошибки.
const error = data.find(isPromiseRejected)?.reason;
if (error) {
console.error("Ошибка отклонённого промиса:", error);
}
// Проверяем, что все промисы успешно выполнены.
const allFulfilled = data.every(isPromiseFulfilled);
if (allFulfilled) {
console.log("Все промисы успешно выполнены!");
// Получаем массив всех успешных значений.
const results = data.filter(isPromiseFulfilled).map(result => result.value);
console.log("Результаты всех промисов:", results);
} else {
console.warn("Некоторые промисы завершились с ошибкой.");
}
}
run();
Promise.allSettled
в JavaScript используется для одновременного выполнения нескольких промисов и получения результатов всех этих промисов, независимо от того, были ли они выполнены успешно (resolved) или завершились с ошибкой (rejected). В отличие от Promise.all
, который отклоняется при первом же отклоненном промисе, Promise.allSettled
всегда выполняется (resolve), возвращая массив объектов, описывающих состояние каждого промиса.
Promise.allSettled
?
Зачем использовать - Обработка независимых задач: Когда вам нужно выполнить несколько независимых асинхронных операций, и важно получить информацию о результате каждой из них, даже если некоторые операции завершатся с ошибкой. Например, загрузка данных из нескольких источников, где неудача одной загрузки не должна блокировать обработку результатов других.
- Улучшение обработки ошибок:
Promise.allSettled
позволяет обрабатывать ошибки отдельных промисов без прерывания всего процесса. Вы получаете информацию о причинах ошибок, что упрощает отладку и обработку исключительных ситуаций. - Более полная картина: Вы получаете полную информацию о состоянии всех промисов, что полезно для мониторинга и логирования.