我应该将await用于异步功能的调用堆栈有多远?

时间:2020-11-03 19:24:34

标签: javascript reactjs asynchronous async-await

我正在使用打字稿/反应,对异步功能的理解是很基本的。

我必须进行两个API调用,并且具有从异步UI调用它们的函数。我绝对需要完成这些调用才能正确呈现组件,但是感觉到整个组件的功能必须声明为异步才能发生。

我在getOverview()中通过添加等待来解决了一个问题,但是现在,我的问题是createPage()函数不等待getOverview()返回的列表中包含项目以便对其执行任何操作,因此最终会出错。我还需要等待此功能吗?

等待的人不断攀升,我不知道它是否正确。

class overview extends React.Component<any, any> {
  
  constructor(props) {
    super(props);
    this.state = {
      overviewList: [],
    };
  }

  async callAPI1() {
    return await api1()
      .then((result) => {
        if (result.status_code === 200) {
          // return result data
        } else {
          // error redirect
        }
      });
  }

  async callAPI2() {
    return await api2()
      .then((result) => {
        if (result.status_code === 200) {
          // return result data
        } else {
          // error redirect
        }
      });
  }

  async getOverview() {
    const list = [];
    list.concat(await this.callAPI1());
    list.concat(await this.callAPI2());

    this.setState({overviewList: list});
    return list;
  }

  createPage() {
    const overview = this.getOverview();
    return overview[1];
  }

  render() {
    return (
      <div>
        <h1>Header</h1>
        { this.createPage() }
      </div>
    );
  }
}

1 个答案:

答案 0 :(得分:1)

我怀疑您想为React内部发生的每个渲染调用外部API。因此,您通常不会在render函数内部调用调用API调用的方法。它们主要在componentDidMount和/或componentDidUpdate内部使用。

以下是基于您的代码的示例:

class overview extends React.Component<any, any> {
  constructor(props) {
    super(props);
    this.state = {
      overviewList: [],
    };
  }

  async callAPI1() {
    return this.trowIfNot200(await api1());
  }

  async callAPI2() {
    return this.trowIfNot200(await api2());
  }

  throwIfNot200(result) {
    if (result.status_code === 200) {
      return result;
    } else {
      throw result;
    }
  }

  async componentDidMount() {
    try {
      const overviewList = await Promise.all([this.callAPI1(), this.callAPI2()]);
      this.setState({overviewList});
    } catch (error) {
      this.setState({error: "There was a problem loading external data."}));
    }
  }

  render() {
    if (this.state.error) {
      return <div>{this.state.error}</div>;
    } else {
      return (
        <div>
          <h1>Header</h1>
          { this.state.overviewList[1] }
        </div>
      );
    }
  }
}

请注意,只要数据仍在加载,this.state.overviewList[1]将返回undefined。对于undefinednullfalse的值,React不会呈现任何内容。

ReactDOM.render(
  <div>a {undefined} b {null} c {false} d</div>,
  document.querySelector("#root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>