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

В чем разница между методами Promise.race и Promise.any?

2.2 Middle🔥 301 комментариев
#JavaScript Core

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

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

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

Разница между Promise.race и Promise.any

Это два похожих на первый взгляд метода для работы с массивом Promise'ов, но они имеют принципиально разное поведение. Нужно четко понимать, когда использовать каждый из них.

Promise.race — первый результат (успех или ошибка)

Promise.race() возвращает Promise, который разрешается или отклоняется со значением первого завершённого Promise'а — неважно, успешно он завершился или с ошибкой.

const promise1 = new Promise((resolve) => setTimeout(() => resolve('First'), 100))
const promise2 = new Promise((resolve) => setTimeout(() => resolve('Second'), 500))
const promise3 = new Promise((reject) => setTimeout(() => reject('Error'), 50))

// Пример 1: первым завершится promise3 с ошибкой
Promise.race([promise1, promise2, promise3])
  .then(result => console.log('Success:', result))
  .catch(error => console.log('Error:', error))  // Error: Error

// Пример 2: используем только успешные promises
Promise.race([promise1, promise2])
  .then(result => console.log('Success:', result))  // Success: First

Promise.any — первый успешный результат

Promise.any() возвращает Promise, который разрешается со значением первого успешно завершённого Promise'а. Если все Promise'ы отклонены, выбросит ошибку AggregateError.

const promise1 = new Promise((reject) => setTimeout(() => reject('Error 1'), 100))
const promise2 = new Promise((resolve) => setTimeout(() => resolve('Second'), 200))
const promise3 = new Promise((reject) => setTimeout(() => reject('Error 3'), 50))

// Вернёт 'Second' — первый успешный
Promise.any([promise1, promise2, promise3])
  .then(result => console.log('Success:', result))  // Success: Second
  .catch(error => console.log('All failed:', error.errors))

// Все Promise'ы отклонены
Promise.any([
  Promise.reject('Error 1'),
  Promise.reject('Error 2'),
  Promise.reject('Error 3')
])
  .catch(error => {
    console.log('AggregateError:', error.errors)
    // ['Error 1', 'Error 2', 'Error 3']
  })

Практические примеры использования

Promise.race — timeout реализация

function fetchWithTimeout(url, timeoutMs) {
  const fetchPromise = fetch(url)
  const timeoutPromise = new Promise((_, reject) =>
    setTimeout(() => reject(new Error('Timeout')), timeoutMs)
  )
  
  return Promise.race([fetchPromise, timeoutPromise])
}

// Использование
fetchWithTimeout('https://api.example.com/data', 5000)
  .then(response => response.json())
  .catch(error => console.error('Failed:', error))

Promise.any — первый быстрый источник данных

// Есть несколько CDN, берём данные с первого быстрого
function loadImageFromCDN(imageUrl) {
  const cdnServers = [
    'https://cdn1.example.com/',
    'https://cdn2.example.com/',
    'https://cdn3.example.com/'
  ]
  
  const promises = cdnServers.map(cdn =>
    fetch(cdn + imageUrl).then(r => {
      if (!r.ok) throw new Error('Failed')
      return r.blob()
    })
  )
  
  return Promise.any(promises)
}

loadImageFromCDN('image.jpg')
  .then(blob => URL.createObjectURL(blob))
  .catch(error => console.error('All CDNs failed:', error))

Таблица сравнения

Ключевые различия в одной таблице для быстрого запоминания.

Когда использовать что

Promise.race используй когда нужен первый результат независимо от статуса (успех или ошибка). Идеален для timeout'ов и отмены операций.

Promise.any используй когда нужен первый успешный результат. Лучше всего подходит для работы с резервными источниками данных и гарантирования успеха при множественных попытках.