皆さんこんにちは!
皆さんは何気なく非同期処理においてthenとcatchを使っていると思います。
ただ何となく使っていると落とし穴にはまります。
以下の例を見て下さい。
const user = this.$auth.currentUser
const func = this.$function.httpsCallable('updateEmailVerified')
func()
.then(() => {
alert('処理完了')
user.reload()
})
.catch(() => {
alert('エラー発生')
})
これはFirebasFunctionsを使ってとある処理を行っています。
本来なら処理が正しく行われたらthenで処理を行い、何かしらエラーが起きた場合はcatchで処理を行うと誰もが予想すると思います。
なんとこの処理thenとcatch両方の処理が行われ、alert('処理完了')が表示された後にalert('エラー発生')も表示されてしまいます😨
一度catchとはどういうものなのかを調べました。
・Promise が reject したもの
・catch 以前に Promise call 後に throw された例外
catchはこの二つのエラーをキャッチします。
つまり、非同期処理関数、今回で言うとfunc()が起こしたエラーとcatchより前の処理then()内で起こったエラーの2つをキャッチします。
これは恐らく初心者の方で知っている方はほぼいないでしょう。
なので、今回の処理では恐らくuser.reload()がエラーを起こしてしまい、alert('処理完了')と表示された後にalert('エラー発生')が表示されます。
user.reload()を消せばいいのですが、練習も兼ねて以下のようにthenとcatchの順番を逆にすることでthenとcatch別々に処理が行われるようになりました。
const user = this.$auth.currentUser
const func = this.$function.httpsCallable('updateEmailVerified')
func()
.catch(() => {
alert('エラー発生')
})
.then(() => {
alert('処理完了')
user.reload()
})
ただ、一概にはcatch→thenとすることが正しいとは言えませんね。
この順番裏を返せばthen内で起こったエラーをキャッチできないので、then()内の処理を多く行っている場合はthen→catchの方が良さそうですね。
逆に少ない処理の時はcatch→thenとしてやるのもアリですね。
少し調べただけなので、鵜呑みにはしないでください!!
悪魔で僕個人の見解なので!
詳しく知っている方はぜひコメント欄にてご指摘頂けると幸いです。
中々見ないエラーで一度はまた2,3時間くらい時間を潰すのではと思ったのですが、意外と早く解決できたので良かったです。
また、なんとなく使っているものをこれからは理解するようにしていこうかなと思いました。
以上、「非同期処理はthen→catchではなくcatch→thenが正解!?」でした!
良ければ、LGTM、コメントお願いします。
また、何か間違っていることがあればご指摘頂けると幸いです。
他にも初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい!!
Thank you for reading