javascript - componentDidMount 中的异步/等待以正确的顺序加载

标签 javascript reactjs

我在以正确的顺序加载多个函数时遇到了一些麻烦。从我下面的代码中,第一个和第二个函数是获取 companyID companyReference 并且不相互依赖。

第三个函数需要第一个和第二个函数设置的state,以实现获取companyName的目的。

async componentDidMount() {
    const a = await this.companyIdParams();
    const b = await this.getCompanyReference();
    const c = await this.getCompanyName();
    a;
    b;
    c;
  }

  componentWillUnmount() {
    this.isCancelled = true;
  }

  companyIdParams = () => {
    const urlString = location.href;
    const company = urlString
      .split('/')
      .filter(Boolean)
      .pop();
    !this.isCancelled &&
      this.setState({
        companyID: company
      });
  };

  getCompanyReference = () => {
    const { firebase, authUser } = this.props;
    const uid = authUser.uid;
    const getUser = firebase.user(uid);
    getUser.onSnapshot(doc => {
      !this.isCancelled &&
        this.setState({
          companyReference: doc.data().companyReference
        });
    });
  };

  getCompanyName = () => {
    const { firebase } = this.props;
    const { companyID, companyReference } = this.state;
    const cid = companyID;
    if (companyReference.includes(cid)) {
      const getCompany = firebase.company(cid);
      getCompany.onSnapshot(doc => {
        !this.isCancelled &&
          this.setState({
            companyName: doc.data().companyName,
            loading: false
          });
      });
    } else if (cid !== null && !companyReference.includes(cid)) {
      navigate(ROUTES.INDEX);
    }
  };

如何在 componentDidMount 中实现这个?

最佳答案

setState 是异步的,因此您无法确定何时以同步方式更新状态。

1) 我建议您不要将 componentDidMount 与 async 一起使用,因为该方法属于 React 生命周期。

相反你可以这样做:

componentDidMount() {
  this.fetchData();
}

fetchData = async () => {
  const a = await this.companyIdParams();
  const b = await this.getCompanyReference();
  const c = await this.getCompanyName();
}

2)

companyIdParams 方法没有返回值,因此您无需等待。 如果您需要等待,我会在 setState 完成时返回一个 promise ;

companyIdParams = () => {
  return new Promise(resolve => {
    const urlString = location.href;
    const company = urlString
      .split('/')
      .filter(Boolean)
      .pop();
    !this.isCancelled &&
      this.setState({
        companyID: company
      }, () => { resolve() });
  });
};

getCompanyReference 相同:

getCompanyReference = () => {
  return new Promise(resolve => {
    const { firebase, authUser } = this.props;
    const uid = authUser.uid;
    const getUser = firebase.user(uid);
    getUser.onSnapshot(doc => {
      !this.isCancelled &&
        this.setState({
          companyReference: doc.data().companyReference
        }, () => { resolve() });
    });
  });
};

3)

如果你想并行化promise,你可以将之前的代码改成这样:

const [a, b] = await Promise.all([
  await this.companyIdParams(),
  await this.getCompanyReference()
]);

4)

根据您的代码,第三个 promise 不是 promise ,因此您可以(再次;)更新上面的代码:

const [a, b] = .....
const c = this.getCompanyName()

编辑:要点不是要遵循的步骤

关于javascript - componentDidMount 中的异步/等待以正确的顺序加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54155902/

相关文章:

javascript - "this"in jQuery $(selector).每个函数引用页面

javascript - 如何在 Angular 指令中使用 <head> 标签

javascript - react native-在组件中插入图像

javascript - 查询特定的GET字段?

reactjs - 缺少 Prop reactjs proptypes 中的错误映射

architecture - 从外部访问 React 状态

javascript - 带有 json.stringify 替换函数的嵌套键

JavaScript/PHP : Get input from prompt and update the database

javascript - 如何从 iframe 中取出菜单并显示在两个 iframe 上?

html - 并非所有行都显示在 Material-UI DataGrid 上