かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

TypeScript Promise.allSettled で成功したものだけフィルタリングしたい

typescript: "4.9.5"

Promise.allSettled

Promise.allSettled()
Promise.allSettled() は静的メソッドで、入力としてプロミスの反復可能オブジェクトを受け取り、単一の Promise を返します。この返されたプロミスは、入力のすべてのプロミスが決定したとき(空の反復可能オブジェクトが渡された場合を含む)に履行され、各プロミスの結果を記述するオブジェクトの配列が返されます。
Promise.allSettled() は、通常、正常に完了するために互いに依存しない複数の非同期タスクがある場合、または各プロミスの結果を常に知りたい場合に使用されます。 それに対して、 Promise.all() が返すプロミスは、タスクが他にも依存している場合や、どれかが拒否されたらすぐに拒否したい場合により適しているかもしれません。
cf. Promise.allSettled() - JavaScript | MDN

Promise.all との違い

Promise.all()
Promise.all() は、入力されたプロミスのいずれかが拒否されると直ちに拒否されます。それに対して、Promise.allSettled() が返すプロミスは、入力されたプロミスのいずれかが拒否されたかどうかに関わらず、すべての入力されたプロミスが完了するのを待ちます。
cf. Promise.all() - JavaScript | MDN

非同期処理の結果に依存がなく、実行できるものは全部実行したい時は Promise.allSettled を使うイメージ

TypeScript で Promise.allSettled の返り値を成功した値だけにフィルタリングする

Promise.allSettled の返り値は、非同期処理が成功した結果と失敗した結果が混ざっているので、成功したものだけ / 失敗したものだけでフィルタリングしたい事が当然ある。TypeScript で。

Promise.allSettled() の返り値は {status: "fulfilled" | "rejected", value?: any, reason?: string (Error message)} の配列なので status でフィルタリングすれば良い

Promise.allSettled で返却されるデータの型は次のようになっているので、これを使ったフィルターを作成する

allSettled<T extends readonly unknown[] | []>(values: T): Promise<{ -readonly [P in keyof T]: PromiseSettledResult<Awaited<T[P]>>; }>;

type PromiseSettledResult<T> = PromiseFulfilledResult<T> | PromiseRejectedResult;

成功 status: "fulfilled" のデータだけをフィルタリング

export const assertFulfilledFilter = <T>(
  input: PromiseSettledResult<T>
): input is PromiseFulfilledResult<T> => input.status === "fulfilled";


const App = async () => {
  const res = await Promise.allSettled(
    some.map(async (item) => await fetcher(item))
  );
  const SuccessedData = res.filter(assertFulfilledFilter);
}

失敗 status: "rejected" のデータだけをフィルタリング

export const assertRejectedFilter = <T>(
  input: PromiseSettledResult<T>
): input is PromiseRejectedResult<T> => input.status === "rejected";

const App = async () => {
  const res = await Promise.allSettled(
    some.map(async (item) => await fetcher(item))
  );
  const FailedData = res.filter(assertRejectedFilter);
}

 
おわり₍ ᐢ. ̫ .ᐢ ₎


[参考]