Как узнать при выполнении нескольких Promise какие упали и какие выполнились?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Обработка нескольких Promise и анализ их статусов
При работе с несколькими асинхронными операциями, которые представлены объектами Promise, возникает необходимость отслеживать их состояние выполнения. Для решения этой задачи в JavaScript существуют несколько подходов, каждый из которых подходит для разных сценариев.
Метод Promise.allSettled()
Наиболее прямой и современный способ — использование метода Promise.allSettled(), который специально разработан для этой цели. Этот метод возвращает новый промис, который исполняется, когда все переданные промисы завершаются (независимо от успеха или неудачи).
const promise1 = Promise.resolve('Успех 1');
const promise2 = Promise.reject(new Error('Ошибка 2'));
const promise3 = Promise.resolve('Успех 3');
Promise.allSettled([promise1, promise2, promise3])
.then((results) => {
results.forEach((result, index) => {
console.log(`Промис ${index + 1}:`, {
статус: result.status,
значение: result.value,
причина: result.reason
});
if (result.status === 'fulfilled') {
console.log(`✓ Промис ${index + 1} выполнился:`, result.value);
} else {
console.log(`✗ Промис ${index + 1} упал:`, result.reason);
}
});
});
Каждый элемент в массиве результатов имеет структуру:
status— строка'fulfilled'или'rejected'value— значение выполненных промисов (только приstatus: 'fulfilled')reason— причина отказа (только приstatus: 'rejected')
Альтернативные подходы
1. Обработка каждого промиса индивидуально
Можно обернуть каждый промис в обработку, которая сохраняет информацию о его статусе:
const promises = [
Promise.resolve('data1'),
Promise.reject('error2'),
Promise.resolve('data3')
];
const statuses = [];
promises.forEach((promise, index) => {
promise
.then(result => {
statuses[index] = { status: 'fulfilled', value: result };
})
.catch(error => {
statuses[index] = { status: 'rejected', reason: error };
});
});
// Проверяем статусы после завершения всех промисов
Promise.allSettled(promises).then(() => {
console.log('Все статусы:', statuses);
});
2. Использование Promise.all() с обработкой ошибок
Promise.all() останавливается при первой ошибке, но можно модифицировать подход:
const promises = [
Promise.resolve('data1'),
Promise.reject('error2'),
Promise.resolve('data3')
];
const wrappedPromises = promises.map(p =>
p.then(
value => ({ status: 'fulfilled', value }),
reason => ({ status: 'rejected', reason })
)
);
Promise.all(wrappedPromises)
.then(results => {
results.forEach((result, index) => {
console.log(`Промис ${index}:`, result);
});
});
Сравнение методов
| Метод | Преимущества | Недостатки |
|---|---|---|
Promise.allSettled() | Специально создан для этой задачи, чистый API, стандартный подход | Поддерживается не в очень старых браузерах |
| Индивидуальная обработка | Полный контроль над каждым промисом | Более многословный код |
Promise.all() с оберткой | Работает в старых средах | Требует дополнительной обертки |
Практические рекомендации
- Для современных приложений всегда предпочитайте
Promise.allSettled()— это наиболее выразительный и понятный способ. - Если важна производительность при большом количестве промисов,
Promise.allSettled()обычно оптимален. - Для совместимости со старыми браузерами используйте полифил или подход с оберткой промисов.
- При отладке можно добавить идентификаторы к промисам для более простого отслеживания:
const createTrackablePromise = (promise, id) => {
return promise
.then(value => ({ id, status: 'fulfilled', value }))
.catch(error => ({ id, status: 'rejected', error }));
};
Пример полного решения с анализом
async function analyzePromises(promiseArray) {
const results = await Promise.allSettled(promiseArray);
const analysis = {
fulfilled: results.filter(r => r.status === 'fulfilled'),
rejected: results.filter(r => r.status === 'rejected'),
total: results.length,
successRate: (results.filter(r => r.status === 'fulfilled').length / results.length) * 100
};
console.log('Анализ выполнения промисов:');
console.log(`Успешно: ${analysis.fulfilled.length}`);
console.log(`С ошибками: ${analysis.rejected.length}`);
console.log(`Процент успеха: ${analysis.successRate.toFixed(2)}%`);
return analysis;
}
Ключевой вывод: Современный JavaScript предоставляет инструменты, которые делают анализ выполнения нескольких промисов простым и предсказуемым. Выбор метода зависит от требований к совместимости и конкретного случая использования, но Promise.allSettled() должен быть вашим первым выбором для новых проектов.