JavaScript Promise.any()

概要: このチュートリアルでは、JavaScriptのPromise.any()メソッドを使用してPromiseを構成する方法を学びます。

JavaScript Promise.any()メソッドの紹介

Promise.any()メソッドは、Promiseオブジェクトのリストをイテラブルオブジェクトとして受け入れます。

Promise.any(iterable);Code language: JavaScript (javascript)

イテラブルオブジェクト内のPromiseのいずれかが履行された場合、Promise.any()は、履行されたPromiseの結果である値に解決される単一のPromiseを返します。

この図では

  • promise1は、t1で値v1に解決されます。
  • promise2は、t2で値v2に解決されます。
  • Promise.any()は、t1promise1の結果である値v1に解決されるPromiseを返します。

Promise.any()は、イテラブルオブジェクト内の一部のPromiseが拒否された場合でも、最初に履行されたPromiseで履行されるPromiseを返します。

この図では

  • promise1は、t1errorで拒否されます。
  • promise2は、t2で値v2に履行されます。
  • Promise.any()は、promise2の結果である値v2に解決されるPromiseを返します。 Promise.any()メソッドは、拒否されたPromise(promise1)を無視することに注意してください。

イテラブルオブジェクト内のすべてのPromiseが拒否された場合、またはイテラブルオブジェクトが空の場合、Promise.any()は、すべての拒否理由を含むAggregateErrorで拒否されるPromiseを返します。 AggregateErrorErrorのサブクラスです。

この図では

  • promise1は、t1error1で拒否されます。
  • promise2は、t2error2で拒否されます。
  • Promise.any()は、拒否されたすべてのPromiseのerror1error2を含むAggregateErrorで、t2で拒否されるPromiseを返します。

JavaScript Promise.any()の例

Promise.any()メソッドを使用する例をいくつか示します。

1) すべてのPromiseが履行された例

次の例は、すべてのPromiseが履行された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);
});
Code language: JavaScript (javascript)

出力

Promise 1 fulfilled
Returned Promise
1
Promise 2 fulfilledCode language: JavaScript (javascript)

仕組み

  • まず、1秒後に値1に解決される新しいPromise p1を作成します。
  • 次に、2秒後に値2に解決される新しいPromise p2を作成します。
  • 3番目に、2つのPromise p1p2を使用するPromise.any()メソッドを使用します。 Promise.any()は、1秒後に最初に履行されたPromise(p1)の値1に解決されるPromise pを返します。

2) 1つのPromiseが拒否された例

次の例では、拒否されたPromiseを含むPromiseリストで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);
});
Code language: JavaScript (javascript)

出力

Promise 1 rejected
Promise 2 fulfilled
Returned Promise
2Code language: JavaScript (javascript)

この例では、Promise.any()は拒否されたPromiseを無視します。 p2が値2で解決されると、Promise.any()p2の結果と同じ値に解決されるPromiseを返します。

3) すべてのPromiseが拒否された例

次の例は、すべてのPromiseが拒否された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);
});
Code language: JavaScript (javascript)

出力

Promise 1 rejected
Promise 2 rejected
Returned Promise
[AggregateError: All promises were rejected] [ 'error1', 'error2' ]Code language: JavaScript (javascript)

この例では、p1p2はどちらも文字列error1error2で拒否されました。 したがって、Promise.any()メソッドは、拒否されたPromiseのすべてのエラーを含むerrorsプロパティを持つAggregateErrorオブジェクトで拒否されました。

JavaScript Promise.any()メソッドを使用する場合

実際には、Promise.any()を使用して、最初に履行されたPromiseを返します。 Promiseが履行されると、Promise.any()メソッドは他のPromiseが完了するのを待ちません。 つまり、Promise.any()は、Promiseが履行された後、ショートサーキットします。

たとえば、2つ以上のコンテンツ配信ネットワーク(CDN)によって提供されるリソースがあるとします。 最初に利用可能なリソースを動的にロードするには、Promise.any()メソッドを使用できます。

次の例では、Promise.any()メソッドを使用して2つの画像を取得し、最初に利用可能な画像を表示します。

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>Code language: JavaScript (javascript)

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);
  });
Code language: JavaScript (javascript)

仕組み

  • まず、fetch APIを使用してURLから画像のブロブを取得するgetImageBlob()関を定義します。 getImageBlob()は、画像ブロブに解決されるPromiseオブジェクトを返します。
  • 次に、画像をロードする2つのPromiseを定義します。
  • 3番目に、Promise.any()メソッドを使用して、最初に利用可能な画像を表示します。

まとめ

  • JavaScriptのPromise.any()メソッドを使用して、Promiseのリストを取得し、最初に履行されたPromiseを返します。

クイズ

このチュートリアルは役に立ちましたか?