【问题标题】:Axios nested request function returnaxios嵌套请求函数返回
【发布时间】:2019-09-19 09:07:04
【问题描述】:

我正在尝试从 API 获取图像数据。为此,我首先需要获取它的 ID,然后使用它来获取图像。为了保持干净的代码,我使用了一个函数来做到这一点,当我尝试将响应返回给我调用该函数的组件时遇到问题。

getNextImageData

export const getNextImageData = () => {
  const apiToken = lscache.get('apiToken')
  return(
    axios({
      method: 'get',
      url: 'https://myapiurl/images/',
      params: {
        limit: '1',
        doc_cat: ''
      },
      responseType: 'json'
    })
      .then(response => {
        lscache.set('imageData', response, 30)
        axios({
          method: 'get',
          url: 'https://myapiurl/images/' + response.data[0].id + '/',
        })
          .then(response => {
            return(response.data)
          })
      })
  )
}

我的班级

class MyClass extends Component {
  constructor(props){
    super(props);
    this.state = {
      image: undefined
    }
  }
  async componentDidMount() {
    const data = await getNextImageData()
    this.setState({
      image: data,
    })
  }
  render() {
  // something
  }
}

我没有收到任何返回,当我将代码直接粘贴到我的组件中时,它工作正常,但我想在函数中使用它

【问题讨论】:

  • 你的 getNextImageData 函数没有返回你试图从 axios 等待的承诺。尝试在之前添加 return 语句:return axios({method:'get' ....
  • @jure 不幸的是,我已经尝试过了,我删除了它,因为我认为它会干扰函数返回。但由于它会引起混淆,我会编辑我的问题,谢谢
  • 这样不行。而是从getNextImageData() 返回一个promise,然后将该承诺解析到您的组件中。
  • @TheCoder 我可以解析我的组件中的最后一个promise,好的。但是我有两个嵌套的承诺,我该怎么做?解决组件中的两个嵌套请求?将这两个 axios 调用划分为两个不同的函数?

标签: reactjs promise async-await httprequest axios


【解决方案1】:

我错误地嵌套了它,您不要在另一个 then 中使用 then,而是在同一级别上使用它们。并且每个 axios 调用都遵循return 语句。这样做我什至不需要使用 async/await,我使用了另一个 promise

getNextImageData

export const getNextImageData = () => {
  const apiToken = lscache.get('apiToken')
  return axios({
    method: 'get',
    url: 'https://myapiurl/images/',
    params: {
      limit: '1',
      doc_cat: ''
    },
    responseType: 'json'
  })
    .then(response => {
      lscache.set('imageData', response, 30)
      return axios({
        method: 'get',
        url: 'https://myapiurl/images/' + response.data[0].id + '/',
      })
    })
    .then(response => {
      return response.data
    })
}

我的班级

class MyClass extends Component {
  constructor(props){
    super(props);
    this.state = {
      image: undefined
    }
  }
  componentDidMount() {
    getNextImageData()
    .then(data => {
      this.setState({
        image: data,
      })
    })
  }
  render() {
  // something
  }
}

【讨论】:

    【解决方案2】:

    试试这个:

    export const getNextImageData = async () => {
      const apiToken = lscache.get('apiToken')
       const data = await axios({
          method: 'get',
          url: 'https://myapiurl/images/',
          params: {
            limit: '1',
            doc_cat: ''
          },
          responseType: 'json'
        });
    const firstResponse = await data; //
    // set local storage 
    lscache.set('imageData', firstResponse, 30)
    const second = await axios({
              method: 'get',
              url: 'https://myapiurl/images/' + firstResponse.data[0].id + '/',
            });
    const thirdResponse = await second.data;
    return thirdResponse;
    }
    
    

    成功了吗?

    【讨论】:

      【解决方案3】:

      准备好所有数据后,您必须设置状态。

      所以你在最后一个 axios 调用中设置状态。

      你也可以使用 callbackHandler 或类似的东西来保持你的代码干净。

      class MyClass extends Component {
        constructor(props){
          super(props);
          this.state = {
            image: undefined
          }
        }
        async componentDidMount() {
          const nextImageResponse = await getNextImageData()
          // If your first response is success make the next call
          if( nextImageResponse.hasOwnProperty('data') ){
            lscache.set('imageData', response, 30)
              axios({
                method: 'get',
                url: 'https://myapiurl/images/' + nextImageResponse.data[0].id + '/',
              })
                .then(response => {
                  if( response.hasOwnProperty('data'){
                    this.setState({ image: response.data, nextImage: nextImageResponse.data });       
                  }
              })
          }
        }
        render() {
        // something
        }
      }
      

      【讨论】:

      • 感谢您的回答。但正如我所说,如果我直接在组件中使用我的代码,它也可以工作。我要做的是使用一个函数调用,使代码尽可能干净,使用组件代码之外的axios逻辑
      猜你喜欢
      • 1970-01-01
      • 2018-06-04
      • 1970-01-01
      • 2020-03-25
      • 2021-01-16
      • 2018-06-29
      • 2020-08-04
      • 2022-01-01
      • 1970-01-01
      相关资源
      最近更新 更多