LoginSignup
6

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-12-26

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6