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

Есть ли у Promise фичи которых нет у async/await?

2.0 Middle🔥 211 комментариев
#JavaScript Core

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

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

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

Promise vs async/await — что есть в Promise, чего нет в async/await

Да, есть несколько фич, где Promise мощнее. Это важно для production кода.

1. Promise.all() — параллельное выполнение

Promise.all() может что-то, что сложнее в async/await:

// Promise.all()
const results = await Promise.all([
  fetch('/api/users'),
  fetch('/api/posts'),
  fetch('/api/comments')
]).then(responses => Promise.all(responses.map(r => r.json())));

// Или более кратко
const [users, posts, comments] = await Promise.all([
  fetch('/api/users').then(r => r.json()),
  fetch('/api/posts').then(r => r.json()),
  fetch('/api/comments').then(r => r.json())
]);

// В async/await нужно писать более многословно
const users = await fetch('/api/users').then(r => r.json());
const posts = await fetch('/api/posts').then(r => r.json());
const comments = await fetch('/api/comments').then(r => r.json());
// Это выполняется последовательно!

// Чтобы параллельно в async/await нужна обвязка
const [users, posts, comments] = await Promise.all([
  fetch('/api/users').then(r => r.json()),
  fetch('/api/posts').then(r => r.json()),
  fetch('/api/comments').then(r => r.json())
]);

Promise.all() не останавливается при первой ошибке:

const results = await Promise.all([
  Promise.resolve(1),
  Promise.reject('Error 2'),
  Promise.resolve(3)
]); // Выбросит Error 2

2. Promise.allSettled() — обработка всех результатов

Нет async/await эквивалента!

const results = await Promise.allSettled([
  fetch('/api/users'),
  fetch('/api/posts'),
  fetch('/api/comments')
]);

// Результаты
results.forEach(result => {
  if (result.status === 'fulfilled') {
    console.log('Success:', result.value);
  } else {
    console.log('Error:', result.reason);
  }
});

В async/await нужно писать try/catch для каждого:

const results = [];

try { results.push(await fetch('/api/users')); }
catch (e) { results.push({ error: e }); }

try { results.push(await fetch('/api/posts')); }
catch (e) { results.push({ error: e }); }

try { results.push(await fetch('/api/comments')); }
catch (e) { results.push({ error: e }); }

3. Promise.race() — первый завершённый

Нет встроенного async/await эквивалента:

const result = await Promise.race([
  fetch('/api/fast'),
  fetch('/api/slow'),
  new Promise((_, reject) => 
    setTimeout(() => reject('Timeout'), 5000)
  )
]);
// Результат от первого завершённого Promise

В async/await нужна обвязка:

const timeout = (ms) => 
  new Promise((_, reject) => 
    setTimeout(() => reject('Timeout'), ms)
  );

const result = await Promise.race([
  fetch('/api/data'),
  timeout(5000)
]);

4. Promise.any() — первый успешный

Похоже на race(), но реагирует только на успех:

const result = await Promise.any([
  fetch('https://api1.example.com'),
  fetch('https://api2.example.com'),
  fetch('https://api3.example.com')
]);
// Вернёт первый успешный (даже если остальные ошибаются)

Vs Promise.race():

const race = await Promise.race([p1, p2, p3]);
// Вернёт первый завершённый (даже ошибка)

const any = await Promise.any([p1, p2, p3]);
// Вернёт первый успешный (игнорирует ошибки)

5. then() цепочки для условной логики

Promise.then() удобен для сложных цепочек:

fetch('/api/user')
  .then(r => r.json())
  .then(user => fetch(`/api/user/${user.id}/posts`))
  .then(r => r.json())
  .then(posts => fetch(`/api/posts/${posts[0].id}/comments`))
  .then(r => r.json())
  .then(comments => console.log(comments))
  .catch(error => console.error(error));

В async/await это выглядит проще, но есть минусы:

try {
  const user = await fetch('/api/user').then(r => r.json());
  const posts = await fetch(`/api/user/${user.id}/posts`).then(r => r.json());
  const comments = await fetch(`/api/posts/${posts[0].id}/comments`).then(r => r.json());
  console.log(comments);
} catch (error) {
  console.error(error);
}

6. finally() — гарантированное выполнение

Promise имеет finally(), но в async/await нужно проверять:

// Promise
fetch('/api/data')
  .then(r => r.json())
  .catch(e => console.error(e))
  .finally(() => console.log('Done!')); // Всегда выполнится

// async/await
try {
  const data = await fetch('/api/data').then(r => r.json());
} catch (error) {
  console.error(error);
} finally {
  console.log('Done!');
}

7. Promise.resolve/reject для быстрого результата

Нет прямого async/await эквивалента:

// Сразу resolved Promise
const result = await Promise.resolve('immediate value');

// Сразу rejected Promise
const error = await Promise.reject('immediate error');

// В async/await нужно обвязка
const result = (async () => 'immediate value')();

8. Обработка нескольких ошибок

Promise catch() можно цеплять:

fetch('/api/user')
  .then(r => r.json())
  .catch(e => console.log('First error:', e))
  .then(() => fetch('/api/posts'))
  .catch(e => console.log('Second error:', e));

В async/await нужны вложенные try/catch:

try {
  const user = await fetch('/api/user').then(r => r.json());
} catch (e) {
  console.log('First error:', e);
}

try {
  const posts = await fetch('/api/posts').then(r => r.json());
} catch (e) {
  console.log('Second error:', e);
}

Сравнительная таблица

Фича                    | Promise | async/await
------------------------|---------|------------
Параллельное выполнение | .all()  | Обвязка
Обработка всех результ  | .allSettled() | Обвязка
Первый успешный         | .any()  | Обвязка
Первый завершённый      | .race() | Обвязка
Цепочки логики          | Хорошо  | Хорошо
Обработка ошибок        | .catch()| try/catch
Гарантированное действие| .finally() | finally
Читаемость              | Средняя | Отличная
Дебаг                   | Средний  | Отличный

Когда я использую Promise вместо async/await

1. Параллельные операции:

// Promise.all() более понятен
const [user, posts, comments] = await Promise.all([
  fetchUser(),
  fetchPosts(),
  fetchComments()
]);

2. Обработка нескольких результатов:

const results = await Promise.allSettled([
  operation1(),
  operation2(),
  operation3()
]);

3. Timeout на операцию:

const result = await Promise.race([
  fetch('/api/data'),
  timeout(5000)
]).catch(() => 'Request timed out');

4. Цепочки с условиями:

fetch('/api/data')
  .then(r => r.json())
  .then(data => {
    if (data.needsMore) {
      return fetch(`/api/more/${data.id}`).then(r => r.json());
    }
    return data;
  })
  .then(finalData => console.log(finalData));

Лучший подход — комбинирование

async function getFullUser(userId) {
  try {
    // async/await для основной логики
    const user = await fetch(`/api/users/${userId}`).then(r => r.json());
    
    // Promise.all() для параллельных запросов
    const [posts, comments] = await Promise.all([
      fetch(`/api/users/${userId}/posts`).then(r => r.json()),
      fetch(`/api/users/${userId}/comments`).then(r => r.json())
    ]);
    
    return { user, posts, comments };
  } catch (error) {
    console.error('Failed to load user:', error);
    throw error;
  }
}

Вывод

Promise имеет такие "суперсилы", которых нет в async/await:

  1. Promise.all/allSettled/any/race — встроенные утилиты
  2. Цепочки .then() — для последовательных операций
  3. Меньше кода в некоторых случаях

Но async/await лучше для:

  • Читаемости
  • Синхронного стиля кода
  • Простоты

Используй оба — async/await для основной логики, Promise методы для координации параллельных операций.

Есть ли у Promise фичи которых нет у async/await? | PrepBro