Node jsで始めるfilesystem6 非同期処理2
非同期処理のコードを見易くしてくれるpromiseは単体処理だけでなく配列処理をしてくれるpromise.allやpromise.race等があります。慣れないとややこしいですが特に非同期関数をまとめて処理できるallは便利なので使えるようにしたい所です。
Promise.all(promiseオブべジェクトの配列)
promise allはpromiseオブジェクトを返す関数をarray形式で受け取り並列処理して結果をarray形式で返します。
見た目がすっきりするだけでなく並列処理で同時に処理を始めて全ての処理が終わってから結果を返します。なので普通にpromiseを続けて処理させるより早く結果を得られる。
このコードも返す結果は同じですが一つの処理が終わってから次の処理を始めるのでsettimeOut 2000*3回分の時間が掛かります。
ただし並列処理ではなく順番に一つの処理が終わってから次の処理に移行させたい場合はpromise.allは使えないのでこういった方法で行う事になる。配列内のpromiseの結果がお互い影響しあう場合等は並列処理かどうかで結果が異なってくるので注意してください。
何かのpromise関数でrejectされた場合は中断して最初のrejectの結果のみ返します。どこかでrejectされたら他の結果は返してくれないので注意してください。
Promise.race(promiseオブべジェクトの配列)
promise.raceは配列で渡したpromiseオブジェクトを返す関数の中でも一番早く結果を返した関数の結果のみ返します。
こちらも最初にrejectされた結果が返ってきた場合はrejectのみ返します。最初に返ってきた値がresolveだった場合はそのままresolveを返します。
Promise.allSettled(promiseオブべジェクトの配列)
promise.allSettleは基本promise.allと同じですが配列内の関数にrejectを返すpromiseがあっても処理を中断させず全ての結果を返します。返された結果はオブジェクト形式でresolveならstatusはfulfilledでvalueでresolve関数に渡した値が入ります。rejectされた時はstatusにはrejectedが入り、reasonにrejectに渡した値が入ります。これによりどの関数でrejectされたか、またはresolveされた結果のみ取得したい場合などの効率が格段に良くなります。但しES2020で追加された仕様なので使用する場合はjsやコンパイラーの環境に気をつけてください。
statusにpromiseの結果が入る以外はallと同じ。
rejectされた場合はsatusにrejectが入りvalueの代わりにreasonが入る。
filterでrejectedされたpromiseを削って、mapでvalueのみ拾ってresolveされた結果のvalueのみの配列に変換する。
全てrejectされてもcatchされず次のpromiseへと進むためcatchさせたい時は意図的にrejectを返す必要がある。
全てのpromiseを返す関数からrejectedを受け取ったらエラーを投げてそのままrejectをさらに返す。その後のpromiseの実行はされずcatchされる。