在React中的Promise中调用Async函数

时间:2019-07-07 18:27:08

标签: javascript reactjs asynchronous async-await

我正在React中开发一个应用程序。它有一个简单的搜索框,在Submit上,我正在调用api1,它返回数据数组。 对于数组中的每个项目,我需要调用api2-应该是异步的。 当前的代码是这样的:

onSubmit() { 
    api1(textboxvalue).then(data => { 
        let currentComponent = this      
        if(data matches condition1) {
        currentComponent.state.arrayOfElements1.push(data);
        }               

        if(data matches condition2) {
        currentComponent.state.arrayOfElements2.push(data);
        }               

        const arrayOfElements1 = this.state.arrayOfElements1
        arrayOfElements1.map(function (element) {
        api2(element) -> set this.state.data1loaded

        })

        const arrayOfElements2 = this.state.arrayOfElements2
        arrayOfElements2.map(function (element) {
        api2(element) -> set this.state.data2loaded

    })

}

要求异步检查渲染中的data1loaded和data2loaded状态。但是使用上述代码,只有在api1的承诺完成后才调用render

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您将结果推送到状态,而不是使用会使用新状态重新渲染组件的 setState 方法。这与Promises的异步性质无关,而与React的工作方式有关(简化:更新状态并将状态和prop传递给导致它们呈现的组件)。

我建议在继续前进之前先刷一下React basics

答案 1 :(得分:1)

@amirKovacevic是完全正确的。您永远不要直接更改状态:https://reactjs.org/docs/state-and-lifecycle.html#do-not-modify-state-directly

我不太了解您的代码,但我想您想执行以下操作:

onSubmit() {
  api1(textboxvalue).then(data => {
    if(/* data matches condition1 */) {
      this.setState(prevState => ({
        arrayOfElements1: [...prevState.arrayOfElements1, data]
      }), () => {
        const requests1 = Promise.all(this.state.arrayOfElements1.map(function 
          (element) {
            return api2(element)
          })).then(data => this.setState({ data1loaded: true })) // I assume you want to have an indication loading was complete
      })
    }
  })
}

请注意,由于我没有使用async / await,因此我陷入了回调地狱。还要注意,我使用了setState回调:https://reactjs.org/docs/react-component.html#setstate

设置状态是异步的,因此,在使用setState之后,请勿直接使用它,至少如果要使用新值,则不要这样做。

此外,我的示例仅用于第一个元素数组。

哦,我是SO的新手,如果有什么不符合常规SO注释标准的情况,那么抱歉。 :)