JS Async

Promise.all / race / allSettled / any

Научиться выполнять несколько промисов параллельно и выбирать правильный комбинатор в зависимости от ситуации.

Средний (Intermediate)
Нужно знать:async/await

Кратко

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 — кто первый доставил приз, того и берём.


Примеры

**Самый простой:**

javascript
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 возвращает массив результатов.

**Простой:**

javascript
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: первый завершённый побеждает.

**Реальный пример:**

javascript
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-запросов.

Материалы курса JS Async — PROlab Academy.