Кратко
Promise.all — все должны выполниться (reject при первом reject). Promise.race — первый завершённый (fulfilled или rejected). Promise.allSettled — ждём все, получаем статус каждого. Promise.any — первый fulfilled (игнорирует rejected).
Подробно
Promise.all([p1, p2, p3]):
- Все промисы запускаются параллельно
- Результат: массив всех результатов
- reject: сразу отклоняется с ошибкой первого rejected
const [users, posts] = await Promise.all([ fetch('/api/users').then(r => r.json()), fetch('/api/posts').then(r => r.json()) ]);
Promise.race([p1, p2, p3]):
- Первый завершённый определяет результат
- Остальные игнорируются
- Может вернуть reject!
const result = await Promise.race([ fetch('/api/fast'), fetch('/api/slow') ]);
Promise.allSettled([p1, p2, p3]):
- Ждёт ВСЕ промисы
- Результат: [{status: 'fulfilled', value}, {status: 'rejected', reason}]
- Никогда не reject
const results = await Promise.allSettled([ fetch('/api/a'), fetch('/api/b') ]); results.forEach(r => { if (r.status === 'fulfilled') console.log(r.value); else console.log(r.reason); });
Promise.any([p1, p2, p3]):
- Первый fulfilled определяет результат
- rejected игнорируются
- Reject только если ВСЕ rejected
const result = await Promise.any([ Promise.reject('Ошибка 1'), fetch('/api/primary'), fetch('/api/fallback') ]);
Ментальная модель
Promise.all — команда из 3 спортсменов: все должны финишировать. Promise.race — кто первый добежал, тот и победил. Promise.allSettled — судья записывает результат каждого, независимо от падений. Promise.any — кто первый доставил приз, того и берём.
Примеры
**Самый простой:**
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.resolve(3);
const results = await Promise.all([p1, p2, p3]);
console.log(results); // [1, 2, 3]Promise.all возвращает массив результатов.
**Простой:**
const slow = new Promise(resolve => setTimeout(() => resolve('медленный'), 2000));
const fast = new Promise(resolve => setTimeout(() => resolve('быстрый'), 1000));
const winner = await Promise.race([slow, fast]);
console.log(winner); // 'быстрый' (через 1 сек)Promise.race: первый завершённый побеждает.
**Реальный пример:**
async function fetchWithFallback(urls) {
try {
// Пробуем все URL параллельно, берём первый успешный
return await Promise.any(
urls.map(url => fetch(url).then(r => {
if (!r.ok) throw new Error(r.status);
return r.json();
}))
);
} catch (error) {
// Все URL failed
throw new Error('Все серверы недоступны');
}
}
const data = await fetchWithFallback([
'https://api-primary.example.com/data',
'https://api-backup.example.com/data'
]);Promise.any для fallback-стратегии: основной + запасной сервер.
Частые ошибки
**Неправильно:** Использовать Promise.all когда нужен частичный успех
**Почему:** Promise.all отклоняется при первом reject — даже если 9 из 10 успешны.
**Правильно:** Для частичного успеха используйте Promise.allSettled.
**Неправильно:** Забывать, что Promise.race может reject
**Почему:** Первый завершённый может быть rejected.
**Правильно:** Обрабатывайте reject в Promise.race.
**Неправильно:** Путать Promise.any и Promise.all
**Почему:** Promise.all — все обязательны. Promise.any — нужен хотя бы один.
**Правильно:** all = все. any = хотя бы один.
Важно запомнить
- Promise.all — все fulfilled → массив результатов; reject при первом reject
- Promise.race — первый settled определяет результат
- Promise.allSettled — все settled, массив {status, value/reason}
- Promise.any — первый fulfilled; reject если все rejected
- Выбирайте комбинатор по сценарию, а не по привычке
Связь
Назад: Вы понимаете async/await (JA5) — теперь вы можете управлять параллельными асинхронными операциями.
Вперёд: Следующий урок (JA7) — Fetch API для реальных HTTP-запросов.