最外层的.catch()是否适用于所有链接/嵌套的promisses?

时间:2016-11-19 15:05:02

标签: javascript api reactjs promise redux

我有一个很长的登录过程,它依赖于目前看起来像这样的3个api调用:

export const authenticationSignIn = (email, password) =>
  (dispatch) => {
    dispatch({ type: AUTHENTICATION_REQUEST });
    apiAccountStatus(email, password)
    .then(({ data }) => {
      const status = data.status;
      if (status === 'ACCOUNT_CREATED') {
        apiSignIn(email, password)
        .then(({ data: sessionData }) => {
          apiIndexAccounts()
          .then(({ data: accountsData }) => {
            dispatch({ type: AUTHENTICATION_SUCCESS });
            window.router.transitionTo('/dashboard/home');
          });
        });
      } else if (status === 'SOMETHING ELSE') {
        // TODO: HANDLE SOMETHING ELSE
      }
    })
    .catch(({ response }) => {
      dispatch({ type: AUTHENTICATION_FAILURE });
      dispatch(notificationShow('ERROR', response.data.type));
    });
  };

正如你所看到的那样,这个函数很安静,但是每个嵌套的api调用都依赖于从之前返回的数据,我试图尽可能地清理它(调度位是redux特定的,但是这些基本上解决了传递的任何问题)在)。最后你会看到一个catch语句,我的问题是这个catch语句是否适用于所有promisses或仅apiAccountStatus

1 个答案:

答案 0 :(得分:2)

  

最后你会看到一个catch语句,我的问题是这个catch语句是否适用于所有的承诺?

不,它只适用于外部承诺,即then调用返回的承诺。这需要被拒绝才能激活catch回调。要取消此承诺,apiAccountStatus(…)必须拒绝或then回调必须抛出异常或返回将被拒绝的承诺

最后一件事就是你缺少的东西 - 你在then回调中创造了更多的承诺,但你并没有return它们以便它们不会链接。你必须这样做

export function authenticationSignIn(email, password) {
  return (dispatch) => {
    dispatch({ type: AUTHENTICATION_REQUEST });
    apiAccountStatus(email, password)
    .then(({data: {status}}) => {
      if (status === 'ACCOUNT_CREATED') {
        return apiSignIn(email, password)
//      ^^^^^^
        .then(({ data: sessionData }) => {
          return apiIndexAccounts()
//        ^^^^^^
          .then(({ data: accountsData }) => {
            dispatch({ type: AUTHENTICATION_SUCCESS });
            window.router.transitionTo('/dashboard/home');
          });
        });
      } else if (status === 'SOMETHING ELSE') {
        // TODO: HANDLE SOMETHING ELSE
      }
    })
    .catch(({ response }) => {
      dispatch({ type: AUTHENTICATION_FAILURE });
      dispatch(notificationShow('ERROR', response.data.type));
    });
  };
}