Promise.allでエラーをキャッチ

JavascriptのPromise.allの安全な代替手段

エラーを含むすべての約束を待っています

Javascript開発者の場合は、標準の組み込みオブジェクトPromiseとそのAPI Promise.allを使用している可能性があります。これは、配列で提供されるすべてのPromiseが解決されるまで待機します。これは、ビジネスロジックを続行する前に、さまざまな非同期結果を待つ非常に洗練された方法です。

ただし、このAPIはエラーを処理しません。 promiseの配列で少なくとも1つのエラーが発生すると、関数はすぐに停止し、それ以上の結果は待ちません。

Promise.allSettledはすべての非同期結果を待ちます

幸いなことに、Promise.allSettledと呼ばれる2番目のAPIが利用可能であり、結果が有効かエラーかに関係なく、すべての約束を待つことを保証します。次のコードは、その使用法を示しています。これは非常に単純ですが、多くの頭痛の種を減らすことができます。

Promise.allとの主な違いは、各プロミスが情報のタプルに解決されることです。ここでは、状態(履行済みまたは拒否済み)と値(履行済みの場合)または理由(拒否済みの場合)の両方が利用可能です。 。

空の配列を提供する

注意すべき特別なケースは、Promise.allSettledが入力として空の配列を受け取ると、すぐに空の配列に解決されることです。これは論理的に聞こえ、予想される動作ですが、それでも指摘したいと思います。

/**
 * A simple dummy function that
 * fetches data from multiple
 * endpoints related to a user.
 */
async function fetchUserData(id){
  // A simple array of promises.
  // The first two parameters are
  // mock calls from down below.
  const promises = [
    fetchUserHistory(id),
    fetchUserProfile(id),
    // For testing only, let's throw.
    Promise.reject(new Error('an error'))
];
  
  const values = await Promise.allSettled(promises);
  // values === [
  //    { status: "fulfilled", value: [1, 2, 3] },
  //    { status: "fulfilled", value: {name:"dummy"} },
  //    { status: "rejected", reason: {}
  // ]
}

// The following functions are just mocks
// and should help improve readability
// of the example at the top.

async function fetchUserHistory(id){
  return Promise.resolve([1,2,3]);
}

async function fetchUserProfile(id){
  return Promise.resolve({ name: "dummy" });
}

ご覧のとおり、Promise.allSettledはPromise.allへの非常に優れた追加機能であり、結果に関係なく、すべての結果を待つことができます。このAPIがすべてのユースケースに適合するとは思いませんが、非同期呼び出しをオーバーヘッドのtry-catch-blockでラップする必要はありません。