Метод Promise.any() в JavaScript — как использовать

В этом руководстве вы узнаете, как использовать метод JavaScript Promise.any() для создания промисов.

Метод Promise.any() принимает список объектов Promise как итерируемый объект:

Promise.any(iterable);

Если одно из обещаний в итерируемом объекте выполнено, Promise.any() возвращает одно обещание, которое разрешается в значение, являющееся результатом выполненного обещания:

Promise.any() - диаграмма 1

На этой диаграмме:

  • promise1 в значение v1 в момент времени t1.
  • promise2 преобразуется в значение v2 в t2.
  • Promise.any() возвращает обещание, которое преобразуется в значение v1, являющееся результатом promise1, в момент времени t1.

Promise.any() возвращает промис, который выполняется с любым первым выполненным обещанием, даже если некоторые промисы в итерируемом объекте отклонены:

Диаграмма 2

На этой диаграмме:

  • promise1 отклонено с error в момент времени t1.
  • promise2 выполняется до значения v2 в t2.
  • Promise.any() возвращает обещание, которое преобразуется в значение v2, являющееся результатом promise2. Обратите внимание, что метод Promise.any() игнорирует отклоненное обещание( promise1 ).

Если все промисы в итерируемом объекте отклонены или если итерируемый объект пуст, Promise.any() возвращает промис, который отклоняется с AggregateError, содержащим все причины отклонения. AggregateError является подклассом Error.

Диаграмма 3

На этой диаграмме:

  • promise1 отклонено из-за error1 в момент времени t1.
  • error2 promise2 момент времени t2.
  • Promise.any() возвращает обещание, которое было отклонено в момент времени t2, с AggregateError, содержащим error1 и error2 всех отклоненных обещаний.

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

Давайте рассмотрим несколько примеров использования Promise.any().

1) Пример выполнения всех промисов

В следующем примере демонстрируется метод Promise.any() со всеми выполненными промисами:

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('Promise 1 fulfilled');
    resolve(1);
  }, 1000);
});

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('Promise 2 fulfilled');
    resolve(2);
  }, 2000);
});

const p = Promise.any([p1, p2]);
p.then((value) => {
  console.log('Returned Promise');
  console.log(value);
});

Выход:

Promise 1 fulfilled
Returned Promise
1
Promise 2 fulfilled

Как это работает:

  • Во-первых, создайте новое обещание p1, которое будет разрешаться в значение 1 через одну секунду.
  • Во-вторых, создайте новое обещание p2, которое через две секунды преобразуется в значение 2.
  • В-третьих, используйте метод Promise.any(), который использует два промиса p1 и p2. Promise.any() возвращает обещание p, которое будет преобразовано в значение 1 первого выполненного обещания( p1 ) через одну секунду.

2) Пример отклонения одного обещания

В следующем примере используется метод Promise.any() со списком промисов с отклоненным промисом:

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('Promise 1 rejected');
    reject('error');
  }, 1000);
});

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('Promise 2 fulfilled');
    resolve(2);
  }, 2000);
});

const p = Promise.any([p1, p2]);
p.then((value) => {
  console.log('Returned Promise');
  console.log(value);
});

Выход:

Promise 1 rejected
Promise 2 fulfilled
Returned Promise
2

В этом примере Promise.any() игнорирует отклоненное обещание. Когда p2 разрешается со значением 2, Promise.any() возвращает обещание, которое разрешается в то же значение, что и результат p2.

3) Пример отказа от всех промисов

В следующем примере показано, как использовать метод Promise.any() при отклонении всех промисов:

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('Promise 1 rejected');
    reject('error1');
  }, 1000);
});

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log('Promise 2 rejected');
    reject('error2');
  }, 2000);
});

const p = Promise.any([p1, p2]);
p.catch((e) => {
  console.log('Returned Promise');
  console.log(e, e.errors);
});

Выход:

Promise 1 rejected
Promise 2 rejected
Returned Promise
[AggregateError: All promises were rejected] [ 'error1', 'error2' ]

В этом примере и p1, и p2 были отклонены со строками error1 и error2. Таким образом, метод Promise.any() был отклонен с объектом AggregateError, у которого есть свойство errors, содержащее все ошибки отклоненных промисов.

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

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

Например, у вас есть ресурс, обслуживаемый двумя или более сетями доставки контента(CDN). Чтобы динамически загрузить первый доступный ресурс, вы можете использовать метод Promise.any().

В следующем примере метод Promise.any() используется для получения двух изображений и отображения первого доступного изображения.

Файл index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>JavaScript Promise.any() Demo</title>
    </head>
    <body>
        <script src="js/app.js"></script>
    </body>
</html>

Файл app.js

function getImageBlob(url) {
  return fetch(url).then((response) => {
    if (!response.ok) {
      throw new Error(`HTTP status: ${response.status}`);
    }
    return response.blob();
  });
}

let cat = getImageBlob(
  'https://upload.wikimedia.org/wikipedia/commons/4/43/Siberian_black_tabby_blotched_cat_03.jpg'
);
let dog = getImageBlob(
  'https://upload.wikimedia.org/wikipedia/commons/a/af/Golden_retriever_eating_pigs_foot.jpg'
);

Promise.any([cat, dog])
  .then((data) => {
    let objectURL = URL.createObjectURL(data);
    let image = document.createElement('img');
    image.src = objectURL;
    document.body.appendChild(image);
  })
  .catch((e) => {
    console.log(e.message);
  });

Как это работает:

  • Во-первых, определите функцию getImageBlob(), которая использует API выборки для получения большого двоичного объекта изображения из URL-адреса. getImageBlob() возвращает объект Promise, который разрешается в большой двоичный объект изображения.
  • Во-вторых, определите два обещания, которые загружают изображения.
  • В-третьих, покажите первое доступное изображение с помощью Promise.any().
Рейтинг
( Пока оценок нет )
Александр Русаков / автор статьи
Программист, разработчик, 12 лет опыта работы в крупных компаниях. Быстро освоил typescript, делюсь своими знаниями на страницах этого сайта.
Загрузка ...
JavaScript и TypeScript