LoginSignup
4
2

More than 1 year has passed since last update.

Promiseの配列を順番に実行したい

Posted at

TL;DR

type Supplier<T> = () => T;

export const sequence = <T>(promises: Supplier<PromiseLike<T>>[]): Promise<T[]> => {
  if (promises.length === 0) {
    return Promise.resolve([]);
  }

  return new Promise((resolve, reject) => {
    const results: T[] = [];

    promises
      .reduce((p1: Supplier<PromiseLike<T>>, p2: Supplier<PromiseLike<T>>): Supplier<PromiseLike<T>> => {
        return () => {
          return p1().then((t: T) => {
            results.push(t);

            return p2();
          });
        };
      })()
      .then(
        (t: T) => {
          results.push(t);
          resolve(results);
        },
        (e: unknown) => {
          reject(e);
        }
      );
  });
};

経緯

ときどき Promise<T>[] を0番目から順番に実行してほしいことがあります。こんなときに Promise.all() を使ってしまうととすべての Promise を同時に実行してしまうためこの要件を満たすことができません。そこで0番目の Promise が履行されたら1番目の Promise を、1番目が履行されたら2番目を...といった順次実行ができる Promise の処理を考えてみました。

結論

できれば Promise.all() とシグネチャを同じにしたかったが不可能でした。参考 :point_down:

Promise.all<T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>[]>;

理由は Promise の実行を遅延させるために関数で包んであげないといけなかったからです。

4
2
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
4
2