0
0

More than 1 year has passed since last update.

Promise.all()を自力で実装するとこんな感じ?

Last updated at Posted at 2022-10-01

コード

const all = <T>(...promises: ReadonlyArray<PromiseLike<T>>): Promise<Array<T>> => {
  if (promises.length === 0) {
    return Promise.resolve<Array<T>>([]);
  }

  let rejected = false;
  const map: Map<number, T> = new Map();

  return new Promise<Array<T>>((resolve, reject) => {
    promises.forEach((p: PromiseLike<T>, i: number) => {
      p.then((t: T) => {
        if (rejected) {
          return;
        }

        map.set(i, t);

        if (map.size === promises.length) {
          const values: Array<T> = [];

          for (let i = 0; i < map.size; i++) {
            values.push(map.get(i)!);
          }

          resolve(values);
        }
      }, (e: unknown) => {
        if (rejected) {
          return;
        }

        rejected = true;

        reject(e);
      });
    });
  });
};

がんばったところ

  1. たとえPromise(Like)の終了(fulfilledになる)順番が配列のとおりでなくても、与えられた配列の順番のとおりに解決された値の配列を返す
  2. 途中で例外が投げられた場合、そこで処理を中断する。そのとき例外がいくつあろうと初めの例外を返す

感想

なんとなく使っているPromise.all()だが、大まかな動作だけを再現するならそこまで難しくはなかった。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0