Async和Await在Axios React中不起作用

时间:2018-10-12 17:04:11

标签: javascript reactjs async-await axios

我有问题:

我希望我的axios发出请求,然后发出this.setState,并将结果保存在变量中。

我的代码:

componentDidMount() {
  let mails = [];
  axios.get('/api/employee/fulano')
    .then(res => this.setState({
      employees: res.data
    }, () => {

      this.state.employees.map(i => {
        async axios.get(`/api/status/${i.mail}`)
          .then(res => {
            mails.push(res.data)
            await this.setState({
              mails: mails
            })
          })
          .catch(err => console.log(err))
      })
    }))
    .catch(err => console.log(err))
}

但是它给出了错误的语法。

最佳解释:我想将地图的所有结果保存在变量mails中,以后再使用setState来更改一次结果。

有人可以告诉我我在哪里流浪?拜托。

4 个答案:

答案 0 :(得分:2)

您在错误的地方使用异步等待。 await关键字必须用于包含异步函数的函数

Promise关键字需要用于返回setState的表达式,尽管asyncawait,但它不会返回Promise,因此{{ 1}}不能使用

您的解决方案看起来像

componentDidMount() {
  let mails = [];
  axios.get('/api/employee/fulano')
    .then(res => this.setState({
      employees: res.data
    }, async () => {

      const mails = await Promise.all(this.state.employees.map(async (i) => { // map function contains async code
        try {
             const res = await axios.get(`/api/status/${i.mail}`)
             return res.data;
        } catch(err) { 
            console.log(err)
        }
      })
      this.setState({ mails })
    }))
    .catch(err => console.log(err))
}

答案 1 :(得分:1)

这应该有效:

    componentDidMount() {
        axios.get('/api/employee/fulano')
         .then(res => this.setState({
          employees: res.data
         }, () => {

           this.state.employees.map(i => {
           axios.get(`/api/status/${i.mail}`)
             .then( async (res) => { // Fix occurred here
                let mails = [].concat(res.data)
                await this.setState({
                  mails: mails
             })
          })
          .catch(err => console.log(err))
        })
      }))
         .catch(err => console.log(err))
     }

答案 2 :(得分:1)

您将async放在错误的位置

异步应该放在函数定义中,而不是函数调用中

componentDidMount() {
    let mails = [];
    axios.get('/api/employee/fulano')
    .then(res => this.setState({
        employees: res.data
    }, () => {
        this.state.employees.map(i => {
            axios.get(`/api/status/${i.mail}`)
            .then(async (res) => {
                mails.push(res.data)
                await this.setState({
                    mails: mails
                })
            })
            .catch(err => console.log(err))
        })
    }))
    .catch(err => console.log(err))
}

答案 3 :(得分:1)

async/await.then/.catch混合不是一个好习惯。而是使用其中一个。这是一个使用 ONLY async/await ONLY 一个this.setState()(引用Promise.each函数)的方法的示例:< / p>

componentDidMount = async () => {
  try {    
    const { data: employees } = await axios.get('/api/employee/fulano'); // get employees data from API and set res.data to "employees" (es6 destructing + alias)

    const mails = []; // initialize variable mails as an empty array

    await Promise.each(employees, async ({ mail }) => { // Promise.each is an asynchronous Promise loop function offered by a third party package called "bluebird"
      try {
       const { data } = await axios.get(`/api/status/${mail}`) // fetch mail status data
       mails.push(data); // push found data into mails array, then loop back until all mail has been iterated over
      } catch (err) { console.error(err); }
    })

    // optional: add a check to see if mails are present and not empty, otherwise throw an error.

    this.setState({ employees, mails }); // set employees and mails to state
  } catch (err) { console.error(err); }

}