← Назад к вопросам

Зачем нужен Promise.all?

1.3 Junior🔥 161 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Зачем нужен Promise.all?

Promise.all — это статический метод в JavaScript, который позволяет обработать несколько асинхронных операций параллельно и дождаться завершения всех из них. Это один из самых полезных и часто используемых методов при работе с асинхронным кодом в JavaScript.

Назначение Promise.all

Promise.all принимает массив Promise'ов и возвращает новый Promise, который:

  • Разрешается (resolve) со значением, когда все Promise'ы в массиве разрешены
  • Отклоняется (reject) при первой ошибке в любом из Promise'ов
Promise.all([promise1, promise2, promise3])
  .then(results => {
    // results — массив результатов в том же порядке
    console.log(results); // [result1, result2, result3]
  })
  .catch(error => {
    // Любой Promise был отклонен
    console.error(error);
  });

Основные сценарии использования

1. Загрузка нескольких ресурсов параллельно

// Без Promise.all — последовательно (медленно)
async function loadDataSequential() {
  const user = await fetch('/api/user').then(r => r.json());
  const posts = await fetch('/api/posts').then(r => r.json());
  const comments = await fetch('/api/comments').then(r => r.json());
  // Время: t1 + t2 + t3
  return { user, posts, comments };
}

// С Promise.all — параллельно (быстро)
async function loadDataParallel() {
  const [user, posts, comments] = await Promise.all([
    fetch('/api/user').then(r => r.json()),
    fetch('/api/posts').then(r => r.json()),
    fetch('/api/comments').then(r => r.json()),
  ]);
  // Время: max(t1, t2, t3) — значительно быстрее!
  return { user, posts, comments };
}

2. Обработка коллекции данных

// Загрузить детали для каждого пользователя
const userIds = [1, 2, 3, 4, 5];
const promises = userIds.map(id => 
  fetch(`/api/users/${id}`).then(r => r.json())
);

const users = await Promise.all(promises);
console.log(users); // [user1, user2, user3, user4, user5]

3. Проверка нескольких условий одновременно

async function validateForm(formData) {
  const [emailValid, usernameAvailable, passwordStrong] = await Promise.all([
    checkEmail(formData.email),
    checkUsernameAvailability(formData.username),
    checkPasswordStrength(formData.password),
  ]);

  return emailValid && usernameAvailable && passwordStrong;
}

Обработка ошибок

Одна из важных особенностей Promise.all — при ошибке в одном Promise весь Promise.all отклоняется:

const promises = [
  Promise.resolve(1),
  Promise.reject('Ошибка'),
  Promise.resolve(3),
];

Promise.all(promises)
  .then(results => console.log(results)) // Не выполнится
  .catch(error => console.error(error)); // Выведет Ошибка

Если нужно обработать ошибки отдельно, используй Promise.allSettled:

const promises = [
  Promise.resolve(1),
  Promise.reject('Ошибка'),
  Promise.resolve(3),
];

const results = await Promise.allSettled(promises);
console.log(results);
// [
//   { status: 'fulfilled', value: 1 },
//   { status: 'rejected', reason: 'Ошибка' },
//   { status: 'fulfilled', value: 3 },
// ]

Альтернативы

Promise.race — возвращает результат первого выполненного Promise:

const result = await Promise.race([
  fetch('/api/fast'),
  fetch('/api/slow'),
]);
// Вернёт результат быстрого запроса

Promise.any — возвращает результат первого успешного Promise:

const result = await Promise.any([
  fetch('/api/server1').catch(() => { throw 'Сервер 1 недоступен'; }),
  fetch('/api/server2').catch(() => { throw 'Сервер 2 недоступен'; }),
  fetch('/api/server3').catch(() => { throw 'Сервер 3 недоступен'; }),
]);
// Вернёт результат первого доступного сервера

Производительность

// Promise.all должен ждать 3 сек (максимум из трёх запросов)
Promise.all([
  delay(1000),  // 1 сек
  delay(2000),  // 2 сек
  delay(3000),  // 3 сек <- максимум
]).then(() => console.log('Готово')); // Выведет через 3 сек

Лучшие практики

// 1. Используй async/await для чистоты кода
async function fetchUserData(userId) {
  const [user, posts, profile] = await Promise.all([
    fetchUser(userId),
    fetchPosts(userId),
    fetchProfile(userId),
  ]);
  return { user, posts, profile };
}

// 2. Правильная обработка ошибок
try {
  const results = await Promise.all(promises);
  // Обработка успешных результатов
} catch (error) {
  // Обработка первой ошибки
  console.error('Одна из операций не удалась:', error);
}

// 3. Используй Promise.allSettled для более стойкой обработки
const settled = await Promise.allSettled(promises);
const successful = settled.filter(r => r.status === 'fulfilled').map(r => r.value);
const failed = settled.filter(r => r.status === 'rejected');

Вывод: Promise.all — критически важный инструмент для эффективной параллельной обработки асинхронных операций в JavaScript, значительно улучшающий производительность приложения.

Зачем нужен Promise.all? | PrepBro