В чем разница между методами Promise.race и Promise.any?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между 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 используй когда нужен первый успешный результат. Лучше всего подходит для работы с резервными источниками данных и гарантирования успеха при множественных попытках.