


Promise.any подходит, когда достаточно первого успешно выполненного промиса. Ранний отказ одной операции не завершает общий результат, пока другие ещё могут выполниться успешно. В практикуме Mentoring.digital проверим это без сети, на управляемых задержках.
Promise.race принимает исход первого завершившегося промиса, включая отказ. Promise.any ждёт первый успех и отклоняется только тогда, когда отклонены все входные промисы.
const later = (delay, value, fail = false) =>
new Promise((resolve, reject) => {
setTimeout(() => {
if (fail) reject(value);
else resolve(value);
}, delay);
});
const value = await Promise.any([
later(10, "first request failed", true),
later(30, "available copy"),
later(60, "another copy"),
]);
console.log(value); // available copy
Запустите пример в модуле JavaScript с поддержкой await на верхнем уровне, например в файле .mjs в Node.js. При обычном скрипте поместите код с await внутрь async-функции.
Если все операции отклонены, результатом становится AggregateError. Массив errors содержит причины в порядке входных промисов, а не в порядке времени их завершения.
try {
await Promise.any([
later(30, "A failed", true),
later(10, "B failed", true),
]);
} catch (error) {
if (!(error instanceof AggregateError)) throw error;
console.log(error.errors); // ['A failed', 'B failed']
}
try {
await Promise.any([]);
} catch (error) {
console.log(error.errors); // []
}
Причина отказа промиса не обязана быть объектом Error: в учебном примере переданы строки. В рабочем коде сохраняйте контекст операции и не рассчитывайте, что у каждой причины есть поле message. Пустой набор тоже приводит к отказу, поэтому его полезно проверить до запуска.
Получение первого успеха не отменяет другие запросы и таймеры. Если они расходуют ресурсы, продумайте отдельный механизм отмены, который поддерживает используемый API. Promise.any сам такую отмену не выполняет.
При работе с fetch отдельно определите, какой HTTP-ответ считать успехом: полученный ответ с ошибочным статусом требует проверки приложением. Иначе можно выбрать ответ, который формально получен, но не подходит задаче.
Поменяйте местами задержки успехов, затем сделайте все исходы ошибочными. Сравните Promise.any с Promise.race на том же наборе. Для каждого варианта заранее запишите ожидаемый результат и проверьте, требуется ли вам первый успех или исход первой завершившейся операции.
Разобрать асинхронные сценарии можно на курсе JavaScript, а обработку ошибок приложения проверить с наставником по JavaScript.