首页 > 解决方案 > componentDidMount 中的异步/等待以正确顺序加载

问题描述

我在以正确的顺序加载几个函数时遇到了一些麻烦。从我下面的代码中,第一个和第二个功能是获取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

标签: javascriptreactjs

解决方案


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 完成时返回一个承诺;

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)

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

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

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


推荐阅读