🤔
await/catch を使うときの early return
この記事は ポエム です
try/catchで書くとcatchの中で簡単にearly returnできますよね
(async () => {
try {
await new Promise((_, reject) => {
reject('something went wrong!')
})
} catch(err) {
console.log('caught!', err)
return
}
console.log('ok~~')
})()
// caught! something went wrong!
こんな感じ
個人的にtry/catchの見た目が好きじゃないのでなるべく使いたくないってのもありますが、
Promiseにcatch生えてるのにtryする?って思うんですよね
でも単純に書き換えるだけだと
(async () => {
const ret = await new Promise((_, reject) => {
reject('something went wrong!')
}).catch((err) => {
console.log('caught!', err)
return
})
console.log('ok~~')
})()
// caught! something went wrong!
// ok~~
「ok~~ ☆〜(ゝ。∂)」じゃあないんだよ
でも
(async () => {
let success = true
await new Promise((_, reject) => {
reject('something went wrong!')
}).catch((err) => {
console.log('caught!', err)
success = false
})
if(!success) {
return
}
console.log('ok~~')
})()
// caught! something went wrong!
これじゃダサいですよね
だから最善手は、
戻り値のない処理でもなんとかresolve('_')
とかやって、
Promise<void>
としないように自分ルールを作った上で、
(async () => {
const ret = await new Promise((_, reject) => {
// これはresolveすることないですが…
reject('something went wrong!')
}).catch((err) => {
console.log('caught!', err)
})
if(!ret) {
return
}
console.log('ok~~')
})()
// caught! something went wrong!
とすることかなって思うんです
でも実態がPromise<void>
なのにこれのためにstring返したりするの、
あんまりホメられたことじゃないと思うんですよね
みなさんどうしてるんですか?
やっぱりtry/catchですか?
Discussion
Promiseは非同期処理のコールバック地獄をメソッドチェーンで解決しているので、
JSの構文のtry/catchやfor文が機能しなくなりますね。
(これはPromiseの問題ではなく、非同期処理・イベントループの問題ですが)
なのでPromiseを魔改造して同期っぽく書ける糖衣構文(async/await)を用意して、半ば強引に解決させてます。
それを歪に感じる人が出るのは自然だと思います。
なのに中途半端に使ってしまうから気に入らない結果になったのでしょう。
シンプルにPromiseのthenで繋げば良さそうです。
私はasync/awaitに違和感はあまり感じていないので、
async関数下のtry/catchで大満足です。
そもそもreject関数が早期リターンみたいなものですから、
Promiseの関数の中身を書き換えられるなら、これが良いでしょうね。