在同一个承诺上调用then()两次

时间:2018-04-26 13:47:35

标签: ajax reactjs promise axios

我想在我的React应用程序中为我的所有请求构建一个中央ajax处理程序。它与Redux或类似的东西无关。它只是一个中心交汇点"用于从React组件执行ajax请求。

问题是,我希望能够拦截某些错误,以避免在每次ajax调用中重复它。最后,我想从实际发起请求的组件再次调用then()

这就是我所做的:

import ajax from '../../services/ajax';

componentDidMount() {
ajax('/content')
  .then(({ data }) => {
    this.setState(() => ({ pages: data.content }))
  })
 }

在反应组件中:

 {content: Array(18), status: "ok", errorMessage: null, metaData: null}

这会导致错误: 未捕获(承诺)TypeError:无法读取属性'数据'未定义的

我怎么能两次处理这个承诺?

编辑:这是我的响应对象的样子:

{{1}}

2 个答案:

答案 0 :(得分:1)

试试这个:

  return axios({
    url: window.BASE_API + endPoint,
    method,
    data
   }).then(({ data }) => {
     if (data.status !== "ok") {
        handleError(data.errorMessage);
     } else {
        return Promise.resolve(data);
     }
  }).catch((error) => {
  handleError(error);
 })
 }

你也应该改变这个:

componentDidMount() {
 ajax('/content')
   .then(({ content }) => {
   this.setState(() => ({ pages: content }))
 })
}

答案 1 :(得分:1)

在这种情况下,让API调用返回一个promise本身可能会很好。像这样:

function apiCall(params) {
    return new Promise((resolve, reject) => {
        axios(params)
            .then({data} => { // Note here that you are extracting the property "data" from whatever the axios call returns.
                if(data.status !== 'ok') {
                    reject(data.errorMessage); // Rejects the promise
                } else {
                    resolve(data) // Resolve the data
                }
            )}
            .catch(e => reject(e))
    }
}

然后你会像这样使用它:

apiCall(params)
   // Since you resolved the raw data, no need to use object extraction unless the property you're trying to get out is `data.data`
  .then(data => this.setState({pages: data.content}))
  .catch(e => handleError(e))

这就是你如何有效地制定一个自定义承诺来处理你所谈论的所有错误案例。可能会发生一些事情,但我认为其中一个可能是您首先从axios响应中提取{data},然后使用promise数据而不解析新数据。然后在.then()调用中,再次在那里提取{data}(并且正如错误所述,它是未定义的)。如果你将整个电话包裹在一个新的承诺中,你可以按照你想要的方式处理它(我认为)。