Клавиша / esc

Promise.race()

Запускаем несколько промисов и дожидаемся того, который выполнится быстрее.

Время чтения: меньше 5 мин

Кратко

Скопировано

Метод race() — это один из статических методов объекта Promise. Его используют, чтобы запустить несколько промисов и дождаться того, который выполнится быстрее.

Как пишется

Скопировано

Promise.race() принимает итерируемую коллекцию промисов, чаще всего — массив. Потом метод возвращает новый промис.

Метод завершится, когда завершится самый быстрый из всех переданных. Остальные промисы будут проигнорированы.

Как понять

Скопировано

Гонка промисов с успехом

Скопировано

Создадим несколько промисов, завершающихся без ошибок.

        
          
          const slow = new Promise(resolve => setTimeout(() => resolve(1), 6000))const fast = new Promise(resolve => setTimeout(() => resolve(2), 3000))const theFastest = new Promise(resolve => setTimeout(() => resolve(3), 1000))
          const slow = new Promise(resolve => setTimeout(() => resolve(1), 6000))
const fast = new Promise(resolve => setTimeout(() => resolve(2), 3000))
const theFastest = new Promise(resolve => setTimeout(() => resolve(3), 1000))

        
        
          
        
      

Передадим массив из созданных промисов в Promise.race():

        
          
          Promise.race([slow, fast, theFastest])  .then((value) => {    console.log(value)    // 3  })
          Promise.race([slow, fast, theFastest])
  .then((value) => {
    console.log(value)
    // 3
  })

        
        
          
        
      

В консоль запишется результат выполнения theFastest, так как он выполнился быстрее всех.

Гонка промисов с ошибкой

Скопировано

Создадим несколько промисов, где theFastest завершается с ошибкой.

        
          
          const slow = new Promise(  resolve => setTimeout(() => resolve(1), 6000))const fast = new Promise(  resolve => setTimeout(() => resolve(2), 3000))const theFastest = new Promise(  (resolve, reject) => setTimeout(() => reject('Some error'), 1000))
          const slow = new Promise(
  resolve => setTimeout(() => resolve(1), 6000)
)
const fast = new Promise(
  resolve => setTimeout(() => resolve(2), 3000)
)
const theFastest = new Promise(
  (resolve, reject) => setTimeout(() => reject('Some error'), 1000))

        
        
          
        
      

Передадим массив из созданных промисов в Promise.race():

        
          
          Promise.race([slow, fast, theFastest])  .then((value) => {    console.log(value)    // Промис с ошибкой завершился быстрее —    // эта часть проигнорируется  })  .catch((error) => {    console.log(error)    // 'Some error'  })
          Promise.race([slow, fast, theFastest])
  .then((value) => {
    console.log(value)
    // Промис с ошибкой завершился быстрее —
    // эта часть проигнорируется
  })
  .catch((error) => {
    console.log(error)
    // 'Some error'
  })

        
        
          
        
      

В консоль запишется результат выполнения theFastest, так как он завершился быстрее всех.

Пустой список промисов

Скопировано

Если передать в Promise.race() пустой список, то промис навсегда зависнет в состоянии pending:

        
          
          Promise.race([])  .then((value) => {    console.log(value)    // then никогда не сработает  })  .catch((error) => {    console.log(error)    // catch никогда не сработает  })
          Promise.race([])
  .then((value) => {
    console.log(value)
    // then никогда не сработает
  })
  .catch((error) => {
    console.log(error)
    // catch никогда не сработает
  })

        
        
          
        
      

Отличие от Promise.any()

Скопировано

Как мы уже знаем, Promise.race() завершится, когда завершится самый быстрый из всех переданных промисов. Даже если он завершается с ошибкой.

Promise.any() завершится, когда без ошибки завершится самый быстрый из всех переданных промисов.

Создадим ещё раз несколько промисов, где theFastest завершается с ошибкой:

        
          
          const slow = new Promise(  resolve => setTimeout(() => resolve(1), 6000))const fast = new Promise(  resolve => setTimeout(() => resolve(2), 3000))const theFastest = new Promise(  (resolve, reject) => setTimeout(() => reject('Some error'), 1000))
          const slow = new Promise(
  resolve => setTimeout(() => resolve(1), 6000)
)
const fast = new Promise(
  resolve => setTimeout(() => resolve(2), 3000)
)
const theFastest = new Promise(
  (resolve, reject) => setTimeout(() => reject('Some error'), 1000)
)

        
        
          
        
      

Передадим массив из созданных промисов в Promise.any():

        
          
          Promise.any([slow, fast, theFastest])  .then((value) => {    console.log(value)    // 2  })  .catch((error) => {    console.log(error)    // Сюда мы не попадём  })
          Promise.any([slow, fast, theFastest])
  .then((value) => {
    console.log(value)
    // 2
  })
  .catch((error) => {
    console.log(error)
    // Сюда мы не попадём
  })

        
        
          
        
      

В консоль запишется результат выполнения fast, так как он выполнился быстрее всех и без ошибки. Этот же пример, но с использованием Promise.race() попадает в catch().