开发者问题收集

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

2018-03-10
799

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

我在 React 组件中启动它的调用位于底部,即使 axios 调用在发布时失败,它也会给我是,并且我确实在第二次调用时从捕获中收到错误消息。如果我在其中放置一个 Promise.reject(),它也会被发送但不会被捕获,因为承诺已经返回,我想。

我尝试将整个内容包装在 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')
   });
 }
1个回答

如果您打算使用此 Action Creator 根据先前的异步请求的结果 dispatch 操作,则不应使用 return 关键字从异步操作中返回 Promise。

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

相关地,我建议您调查 Async/Await 的使用情况。此代码构造(和解释难度)正是将 Async/Await 纳入语言的原因。

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

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

还有小提琴: https://jsfiddle.net/0n6to6Lm/21/

如果你想在 React Editor 中设置你的架构,我很乐意帮助你实现它。

Randy Casburn
2018-03-10