14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

配列に格納されている async 関数を順番に実行したい

Posted at

前哨

for await なんて便利な物があるではないか

以下そのまま転載

const asyncIterable = {
  [Symbol.asyncIterator]() {
    return {
      i: 0,
      next() {
        if (this.i < 3) {
          return Promise.resolve({ value: this.i++, done: false });
        }

        return Promise.resolve({ done: true });
      }
    };
  }
};

(async function() {
   for await (let num of asyncIterable) {
     console.log(num);
   }
})();

// 0
// 1
// 2

つまり内部に Promiseawait があるイテレータを for ループで回せる訳ですね。
とすれば配列にたくさん Primise ぶちこんで、こんなかんじに回してあげれば逐次実行できる訳です。

// 関数を遅延実行できるようにする
lazyFunction = (f, ...args) => {
  return () => f(...args)
}

async executePromiseSerearize(ps) {
  const rs = []
  // ps を頭から実行するイテレータを作る
  const executer = async function*(ps){
    const _ps = [].concat(ps)
    while(_ps.length){
      const p = _ps.shift()
      yield await p()
    }
  }
  // イテレータを for of で実行
  for await(const r of executer(ps)){
    rs.push(r)
  }
  return rs
}

// 1秒後に n が出力されて n が帰ってくる
const hogehoge = (n) => new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(n)
    resolve(n)
  }, 1000)
})

const ps = [1,2,3,4,5].map(n => lazyFunction(hogehoge, n))

!(async () => {
  res = await executePromiseSerearize(ps)
  console.log(res)
})()
// 1 から 5 が1秒毎に出力されて最後に配列が出る

でも eslint では非推奨

書いてある事をざっくり言うと 「なんで async でプロセスが並列で処理できるのに逐次実行しようとするの??なんで時間の無駄遣いをしようとするの??バカなの??*ぬの???:angry::angry::angry::angry:

という事ですが……例えばさぁ……WEBスクレイピングするのに何万ページ一気に開いてアクセスするとか……もうDDoS攻撃レベルじゃないですか……

というわけで

非推奨の物でも、使わなきゃいけない事がある。おします。

14
8
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
14
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?