Skip to main content

Що робить Promise.race()?

Що робить Promise.race()

Promise.race(iterable) приймає масив (або будь-який ітерований об'єкт) промісів і повертає новий проміс, який:

  • виконується (fulfilled) або відхиляється (rejected), щойно перший із переданих промісів завершиться - незалежно від того, успішно чи з помилкою.

Тобто "перегони" промісів: хто перший завершиться - той і визначить результат.


Синтаксис

javascript
Promise.race(iterable)

Повертає:

новий Promise, який:

  • завершиться зі значенням першого успішно виконаного промісу (resolve),
  • або впаде з помилкою, якщо першим завершиться той, що зробив reject.

Приклад 1 - хто швидший, той і переміг

javascript
const fast = new Promise(resolve => setTimeout(() => resolve('Швидкий'), 1000)); const slow = new Promise(resolve => setTimeout(() => resolve('Повільний'), 3000)); Promise.race([fast, slow]).then(console.log);

Результат через 1 секунду:

javascript
Швидкий

Другий проміс (slow) продовжить виконуватися у фоні, але результат уже визначено - "перегони" виграв fast.


Приклад 2 - якщо перший проміс завершився з помилкою

javascript
const ok = new Promise(resolve => setTimeout(() => resolve('Все гаразд'), 2000)); const fail = new Promise((_, reject) => setTimeout(() => reject('Помилка!'), 1000)); Promise.race([ok, fail]) .then(console.log) .catch(console.error);

Результат через 1 секунду:

javascript
Помилка!

Навіть попри те, що ok потім успішно виконається, результат усіх перегонів уже вирішено помилкою.


Як це працює під капотом

  1. Усі проміси починають виконуватися одночасно (практично).
  2. Щойно один з них завершився (resolve або reject):
  • результат цього промісу стає результатом усіх перегонів;
  • Promise.race() переходить у стан fulfilled або rejected;
  • інші проміси ігноруються (але не скасовуються).
  1. Решта промісів продовжують виконуватися у фоні, але їхній результат ні на що не впливає.

Приклад 3 - з "таймаутом"

Часта практика: використовувати Promise.race() для встановлення обмеження за часом

javascript
function timeout(ms) { return new Promise((_, reject) => setTimeout(() => reject(`Перевищено час очікування (${ms}мс)`), ms) ); } const fetchData = new Promise(resolve => setTimeout(() => resolve('Відповідь отримано'), 3000) ); Promise.race([fetchData, timeout(2000)]) .then(console.log) .catch(console.error);

Вивід через 2 секунди:

javascript
Перевищено час очікування (2000мс)

Це один з найчастіших сценаріїв застосування Promise.race() - обмеження "зависаючих" операцій (наприклад, запитів).


Приклад 4 - усі проміси миттєві

javascript
Promise.race([ Promise.resolve('Перший'), Promise.resolve('Другий'), Promise.resolve('Третій') ]).then(console.log);

Вивід:

javascript
Перший

Навіть якщо всі виконаються миттєво - перемагає перший за порядком ітерації.


Якщо передати не-проміси

Promise.race() автоматично "обгортає" звичайні значення в Promise.resolve():

javascript
Promise.race([42, Promise.resolve('OK')]).then(console.log); // 42

Відмінність від інших методів

МетодЩо робитьЗавершується колиПри помилці
Promise.all()Чекає всі промісиУсі завершено успішноПадає при першому reject
Promise.allSettled()Чекає всіх, незалежно від результатуУсі завершеноНіколи не падає
Promise.race()Бере перший завершенийПерший resolve або rejectЗалежить від першого промісу
Promise.any()Бере перший успішний (resolve)Перший fulfilledПадає, якщо всі rejected

Проста аналогія

Уяви перегони.

У тебе кілька кур'єрів - хто перший доставить посилку, того результат ти й приймаєш. Решта все ще в дорозі, але тобі вже байдуже, ти отримав потрібне.


ПІДСУМОК

ОсобливістьPromise.race()
ПриймаєМасив (або інший ітерований об'єкт) промісів
Завершується колиПерший проміс виконається або відхилиться
ПовертаєРезультат (або помилку) першого завершеного промісу
Решта промісівІгноруються (але не скасовуються)
Часте застосуванняОбмеження за часом (timeout), конкуренція запитів

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.