Клавиша / 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().