🦠

[JavaScript] PromiseでRejectもしくは例外が発生した場合のawait

2022/05/11に公開

はじめに

JavaScriptのPromiseは、awaitを使えば大分わかりやすくなります。
筆者は、awaitの動作を理解できていたと思っていました。
最近、awaitで待っていたPromiseで例外が発生し、自分の認識と違う動作をしたので記事にしてみることにしました。
そもそも、例外が発生した場合だけでなく、Rejectされた場合に対する認識も間違っていました。

動作確認

Firefox: 100.0 (64 ビット)
JSFiddle: No-Library (pure JS)

コード

Resolveの場合

以下のようなコードの場合、f2resultは、f0が出力した値がそのまま出力されます。
これは、想定していた動作でした。

Rejectの場合

一方、PromiseがRejectされた場合は、以下のような出力を想定していましたが、何も出力されません。

想定していた出力
f1: {"func":"f0","result":false}
f2: {"func":"f0","result":false}

その代わり、コンソールにUncaught (in promise) Object { func: "f0", result: false }のようなメッセージが出力されます。

もっともこれは、awaitの仕様通りで通常の動作です。
自分の認識が間違っていただけでした。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/await

想定通りの動作をさせるためには、RejectされたをPromiseをcatchしなければいけません。
例えば、以下のように修正します。
ここでは、f1しか修正していませんが、場合によってはf2も修正する必要があります。

例外が発生した場合

例外を発生させてみます。
また、何も出力されなくなりました。
そして、コンソールにUncaught (in promise) Error: f0と表示されています。
このメッセージだけだと例外が発生したのかRejectされたのか区別できません。
自分が書いたコードでなかったので、尚更わかりませんでした。

これを修正するには、例外が発生したのでtry/catch文で処理する必要があります。
例えば、以下のようにします。
まあ、実際には、もう少しtry/catch文で返す値なりを考えなければいけないと思いますが。

Discussion