これまで自分は、Promise.allを使ったことがなくPromise.allsettledに関しては名前すら聞いたことがありませんでした・・・そこで、自分と同じような人が少しでも早く理解を深められたらいいなと思いPromise.allとPromise.allsettledについての記事を書いてみました!
#Promiseについて簡単に
JavaScriptの特性として、「非同期処理」というものがあります。同期処理は書かれたコードが上から順番に必ず実行されるのに対し、非同期処理は上から順番に実行されない時もあります。例えば、外部連携などの実行に時間がかかる処理の場合、実行が完全に完了する前に次の処理に走ってしまうことがあります。そのため、
let res = dynamodb.get(params)
console.log(res)
上記のような流れの場合に、非同期処理だと1行目の処理が最後まで終わり変数に代入される前に2行目の処理が実行されエラーになるというパターンが発生することがあります。
ただ、Promiseを使うことで実行する順番を指定することが可能です。
そのため、Promiseにより先ほど説明したようなエラーを防ぐことができます。
Promise.allを使用するメリット
Promise.allを使うメリットとして、時間のかかる非同期処理をたくさん行わないといけない場合に、「無駄なく効率よく並列で実行できる」ことが挙げられます。
例えば、下記のように時間のかかる処理を複数行うとします。
let res_1 = await dynamodb.get(params_1) // 実行を完了するのに1秒
let res_2 = await dynamodb.get(params_2) // 実行を完了するのに2秒
let res_3 = await dynamodb.get(params_3) // 実行を完了するのに3秒
この場合だと、全て実行し終えるのに6秒もかかります。
一方で実装したい機能の関係上、毎回6秒も待ってられない場合を考えてみます。
その場合、下記のようにします。
let [ res_1 , res_2, res_3] = await Promise.all(
dynamodb.get(params_1), dynamodb.get(params_2), dynamodb.get(params_3)
)
そうすると、3つの処理が順番に行われるのではなく、並行で実行されます。
よって、全て実行し終えるのに3秒しかかからないのです。
Promise.all()を使うことで、複数の非同期処理を最速で終わらせることができます。
#Promise.allとPromise.allsettledの違いとは
両者の違いに触れる前に、Promiseは成功した際にはresolveが、失敗した際にはrejectが返されます。(正確にはPromiseのステータスをpendingからfullfilledに変更するために、resolve()を呼び出しrejectedに変更するためにreject()を呼び出します)
では、違いについて見ていきましょう。
Promise.allは、配列内の複数あるPromiseがたった1つでも「reject」を返すと、即終了します。たとえ、それ以外のPromiseが全て順調にうまくいっており、それらの実行が最後まで完了していなかったとしても、途中で終了します。初めはなんで???って感じでした(笑)
それに比べて、Promise.allsettledは配列内のPromiseが「resolve」でも「reject」でも関係なく、全ての処理が終わって初めて完了します。
そのため、「とりあえず、成功・不成功気にせず全てのPromiseを実行したいんだ!」(あ、自分はこれでした笑)と考える方は、Promise.allsettledでその悩みは解決できると思います。
#最後に
あまりQiitaなどを書いたことがないため、拙い文章ではあったと思いますが最後まで読んでくださりありがとうございました!これからも月に2回ほど学んだことをアウトプットしていきます。もう少し文章が上手くなれるように頑張ります笑