javascriptでforEachの時await(Promise・非同期処理)する。

node.jsで非同期プログラムを書いていた時に、2重のforEach内の処理が終わってからresolveしたいと思っていたのですが、意図通りの挙動にならなかったので、忘れないうちに自分用に解決方法をメモしておこうと思います。

上手くいかないパターン

これだと、list2.forEachブロック内の処理が全部終わる前に関数「forEachLoopPromiseTest」がresolveしてしまって、「スクリプト完了!」って出た後で「list2.forEachが完了」だの「list1.forEachが完了」が表示されてしまいます。(本来は両方のforEachが完了してから「スクリプト完了!」となる様に実行したい)

解決のポイント

解決のポイントとしては、以下の3つです。

  • forEachは何も返さないのでawaitしても無駄。(await list1.forEach()…などと書いても待ってくれない。Promiseが返ってこない。)
  • Promise.all()を使う。
  • list2.forEach内に即時実行関数を作成して配列に代入→Promise.all()で確認。

技術的用語

ややこしいのでググってください…

  • Promise.all = Promise.all([PromiseObjectArray]).then(()=>{ // 全部終わったときの処理 })
  • 即時実行関数 = すぐ実行する関数。 ( () => { // ここに処理→Promiseを返す } )();
  • 関数は配列に代入可能。

上手く行ったコード

要するにPromiseを返す関数の中に配列を用意して、Promiseオブジェクトを返す即時実行関数をその配列に代入→Promise.all()で確認して、全部完了したら関数をresolveする。

反省点

まあぶっちゃけネストがややこしい。読みにくい。意図通りには動くのですがもっとすっきりかける方法があるかもしれません。

例えばうまいこと切り分けで別の関数にするとか。上手いこと改善できそうならまた更新します。

質問・コメントなどあればどうぞ