Edited at

非同期通信の書き方の理解の推進

More than 1 year has passed since last update.

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の良さに対する理解が中途半端の時、発生しやすいケースだと思います。旧来の考え方を捨てるのが時間かかるかもしれませんが、新生の物事に抵抗感が自然に発生することを覚悟した上で、常に新しい技術を受け入れることが大事ではないかと思います。