嵌套 API 调用 JavaScript Axios,返回正确的承诺

Nestled API calls in JavaScript Axios, returning the right promise

我正在尝试使用 axios post 数据到我的 API。我需要随请求请求并发送 XSFR 令牌。我正在使用 React、Redux、Thunk 和 Axios。 我需要将其作为 React 组件本身内部的承诺来处理。现在是,但它没有以所需的方式响应。它总是解决承诺,即使 post 失败,只要令牌请求成功。

我在我的 React 组件中启动它的调用在底部,即使 axios 调用在 post 上失败,它也会给我是,我确实从第二次调用的 catch 中得到了错误消息.如果我把 Promise.reject() 放在那里,它也会被发送但未被捕获,因为我认为已经 returned 了一个承诺。

我尝试将整个内容包装在 return Promise.all([getToken()...]) 中。它有效,但行为完全相同,仍然让我从成功接收令牌中得到解决,并忽略了第二个 axios 调用。

操作:

export function Post(data) {

  return (dispatch) => {
    return getToken('csfr')
      .then(response => {
         return axios.post( '/post', {
           request: data,
           token: response,
           apitoken: 'apikey',
         })
         .then(response => {
           dispatch({type: 'POST', payload: response});
         })
         .catch(error => {
           dispatch(errorPopup({visible: true, message: error}));
           throw error;
         });

      })
      .catch(error => {
        dispatch(errorPopup({visible: true, message: error}));
      });

  };
}


export function getToken(tokentype) {
   return axios.post( '/token/' + tokentype, {
     apitoken: 'apikey',
   })
   .then()
   .catch(error => {
     throw error;
   });
}

React 组件(Post 动作使用 Redux 绑定到 props):

componentWillMount() {
  this.props.Post(this.state.data)
  .then(() => {
    console.log('yes')
   })
   .catch(() => {
     console.log('no')
   });
 }

如果您的目的是使用此 Action Creatordispatch 一个基于多个先前异步请求结果的动作,您不应该使用 return 关键字来 return 来自异步操作的 Promise。

删除内部 return 关键字并允许 .then.catch 调度 您的操作。

与此相关,我建议您研究 Async/Await 的使用。这种代码构造(和解释困难)正是 Async/Await 被放入语言中的原因。

以下代码(已修改以满足您的架构)将满足您的用例。请注意,我通过模拟方法等在任何地方都采取了自由。例如,像 fetch()axios 方法 return 一个承诺。我想你会明白要点的。如果您有任何问题,请告诉我。

async function getToken(tokentype) {
  try {
    return await fetch('https://jsonplaceholder.typicode.com/posts/1')
  } catch (error) {
    throw error;
  };
}

function dispatch(data) {
  console.log(data);
}



function Post(data) {
  return async () => {
    try {
      let token = await getToken('csfr');
      let post = await fetch('https://jsonplaceholder.typicode.com/posts/1');
      dispatch({
        type: 'POST',
        payload: post
      });
    } catch (error) {
      dispatch('error: ' + error);
      throw error;
    };
  }
}

let attempt = Post('This is a test');
attempt().then(() => {
  console.log('Completed Post');
})

和fiddle:https://jsfiddle.net/0n6to6Lm/21/

如果您想在 React Editor 中设置您的架构,我很乐意帮助它工作。