Promiseを返す関数を「同期的」に「繰り返し」実行する

プログラミング

jsで実装を進めていると、ちょっと重い処理は自動的に「非同期」で実行してくれます。

それがうれしい時もたくさんあるのですが、繰り返し実行する場合に、前回の実行結果を使って再度実行するなどの実装にはちょっと工夫が必要です。

今回の問題と解決策

今回は、繰り返し実行する場合に、前回の実行結果を使って再度実行するなどの場合を考えます。

繰り返す回数が確定していたり、前回の実行結果を使わず、並列実行して構わないのであればPromise.all()などを使用すれば簡単です。

また非同期実行関数の同期実行版fs.readFileSync()とか)が用意されているのであれば、whileとそれを使えば解決しますね。
ただ、用意されてないことの方が多いです。

上記の理由より、今回はPromiseを返す関数の実行をasync/awaitでもって終了を待ち、その戻り値により、次の実行を決めるというアプローチで実装してみます。

async/await

async function 宣言は、 非同期関数 — AsyncFunction オブジェクトである関数を定義します。非同期関数はイベントループを介して他のコードとは別に実行され、結果として暗黙の Promise を返します。ただし、非同期関数を使用したコードの構文および構造は、通常の同期関数と似たものになります。
async function 式 を使用して非同期関数を定義することもできます。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function

omoiSyori()を実行して、その戻り値を次の実行時の引数として使用する場合を考えてみます。

async function sample() {
  let result

  while (true) {
    result = await omoiSyori(next) // omoiSyori()はPromiseを返す
    let next = result.next

    if (result.length == 0) {
      // ループ終了条件を満たしたらbreakで抜ける
      break
    }
  }
}

sample() // 実行

まとめ

思ったより簡単に実装可能だった。async/awaitは、意外と使う場面多いのでしっかり使いこなせるようにしておく必要がありますね。

参考

非同期関数 - JavaScript | MDN
非同期関数は async キーワードで宣言され、その中で await キーワードを使うことができます。 async および await キーワードを使用することで、プロミスベースの非同期の動作を、プロミスチェーンを明示的に構成する必要なく、よりすっきりとした方法で書くことができます。

タイトルとURLをコピーしました