JavaScript
es6
ECMAScript6
ECMAScript2015
redux-thunk

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

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