最外面的 .catch() 是否适用于所有链接/嵌套的承诺? [英] Will outermost .catch() work for all chained / nested promisses?

查看:11
本文介绍了最外面的 .catch() 是否适用于所有链接/嵌套的承诺?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a bit of a long login process that relies on 3 api calls that looks like this at the moment:

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 语句适用于所有的承诺还是只适用于 apiAccountStatus?

As you can see this function is quiet verbose, but each nested api call relies on data returned from previous and I am trying to clean this up as much as possible (dispatch bits are redux specific, but these essentially fire whatever is passed in). At the end you will see a catch statement, my question is will this catch statement work for all of the promisses or only apiAccountStatus?

推荐答案

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

At the end you will see a catch statement, my question is will this catch statement work for all of the promises?

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

No, it only works for the outer promise, the one returned by the then call. This needs to be rejected for the catch callback to be activated. To get this promise rejected, either apiAccountStatus(…) must reject or the then callback must throw an exception or return a promise that will be rejected.

最后一件事就是你所缺少的——你在那个 then 回调中创建了更多的 promise,但是你没有 return 使它们不会链接起来.你必须做的

This last thing is what you were missing - you were creating more promises inside that then callback, but you weren't returning them so that they will not chain. You have to do

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));
    });
  };
}

这篇关于最外面的 .catch() 是否适用于所有链接/嵌套的承诺?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆