Комбинаторы промисов
Четыре статических метода для работы с группой промисов: all, race, allSettled, any — и когда каждый из них.
Комбинаторы промисов принимают массив промисов и возвращают один общий промис, который завершается по своей логике объединения.
Promise.all — все или ничего
Promise.all ждёт, пока выполнятся все промисы, и отдаёт массив результатов в исходном порядке. Если хотя бы один отклонится — общий промис немедленно отклоняется с этой ошибкой:
const p1 = Promise.resolve(1);
const p2 = new Promise(r => setTimeout(() => r(2), 10));
const p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(values => console.log("all:", values.join(", ")));Вывод:
all: 1, 2, 3
Порядок результатов соответствует порядку в массиве, а не порядку завершения. Теперь — поведение при ошибке:
const ok = Promise.resolve("ok");
const bad = Promise.reject(new Error("упал"));
Promise.all([ok, bad])
.then(v => console.log("успех:", v))
.catch(e => console.log("all отклонился:", e.message));Вывод:
all отклонился: упал
Promise.race — кто первый
Promise.race завершается, как только завершится первый промис — неважно, успехом или ошибкой. Удобно для таймаутов:
const slow = new Promise(r => setTimeout(() => r("медленный"), 50));
const fast = new Promise(r => setTimeout(() => r("быстрый"), 10));
Promise.race([slow, fast]).then(v => console.log("race победитель:", v));Вывод:
race победитель: быстрый
Promise.allSettled — ждём всех, ошибки не страшны
Promise.allSettled дожидается завершения всех промисов и никогда не отклоняется. Возвращает массив объектов { status, value } или { status, reason }. Идеально, когда нужно собрать все результаты, даже если часть упала:
const tasks = [
Promise.resolve("A ок"),
Promise.reject(new Error("B упал")),
Promise.resolve("C ок")
];
Promise.allSettled(tasks).then(results => {
for (const r of results) {
if (r.status === "fulfilled") console.log("успех:", r.value);
else console.log("ошибка:", r.reason.message);
}
});Вывод:
успех: A ок ошибка: B упал успех: C ок
Promise.any — первый успех
Promise.any отдаёт результат первого успешного промиса, игнорируя ошибки. Отклоняется только если упали все (с AggregateError):
const tasks = [
Promise.reject(new Error("первый упал")),
new Promise(r => setTimeout(() => r("второй ок"), 10)),
Promise.reject(new Error("третий упал"))
];
Promise.any(tasks).then(v => console.log("any:", v));Вывод:
any: второй ок
Шпаргалка: когда что
| Метод | Когда завершается | Применение |
all | все успешны / первый упал | нужны ВСЕ результаты, любой сбой критичен |
race | первый любой результат | таймауты, «кто быстрее» |
allSettled | все завершились | собрать отчёт, ошибки не критичны |
any | первый успех / все упали | несколько источников, хватит одного |
Итог
all— «все или ничего», порядок результатов сохраняется.raceиanyловят первого: первый любой против первого успешного.allSettledникогда не падает — даёт полный отчёт по каждому.