ES8から正式にサポートしてくれたasync/awaitにより、Promise非同期処理をすっきりにする方法ですが、それを本当に理解する必要があります。
次の利用場面で具体的な例で考えましょう。
redux-thunkのActionCreatorで非同期通信を実行して、成功した場合、あるアクションをdispatchします。
通信する前に、ローディングインジケータを表示し、終わったら消す処理が必要です。
方法1(Promise案)
export const doIt = () => {
return (dispatch) => {
dispatch(showLoading());
return dispatch(doHttpAction())
.then((res) => {
dispatch(hideLoading());
dispatch(refreshDisplay(res.data));
})
.catch(() => {
dispatch(hideLoading());
});
};
};
方法2(Promise + await案)
export const doIt = () => {
return (dispatch) => {
dispatch(showLoading());
const isSuccess = await dispatch(doHttpAction())
.then((res) => {
dispatch(hideLoading());
return true;
})
.catch(() => {
dispatch(hideLoading());
return false;
});
if (isSuccess) {
dispatch(refreshDisplay(res.data));
}
};
};
方法3(await案)
export const doIt = () => {
return (dispatch) => {
dispatch(showLoading());
try {
await dispatch(doHttpAction());
dispatch(refreshDisplay(res.data));
}
finally {
dispatch(hideLoading());
}
};
};
結論
個人的には方法3のawait案がお好みです。メリットが2つあります。
- 正常系の流れで簡潔でわかりやすい
- 通信失敗の場合、Promise.rejectされたことが自動的に呼び出し元に伝えます
方法2のpromise+await混合案がawaitの良さに対する理解が中途半端の時、発生しやすいケースだと思います。旧来の考え方を捨てるのが時間かかるかもしれませんが、新生の物事に抵抗感が自然に発生することを覚悟した上で、常に新しい技術を受け入れることが大事ではないかと思います。