javascript - 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
?
解决方案
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()
编辑:要点不是要遵循的步骤
推荐阅读
- ruby-on-rails-4 - Redirect_to 声称可以工作,但实际上并没有在浏览器中发生
- wix - Windows 安装程序:哪些文件被视为“版本化”
- android - 在手机上运行应用程序失败(Android Studio)
- java - 来自 Android 的“网络无法访问”,但在 Python 客户端上运行良好
- parsing - 在 LUA 中解析字符串
- java - 从 Java 调用存储过程
- java - 为什么 compareTo BigInteger while 循环不退出?
- html - 当我用关键帧制作另一个动画时,为什么不能为 scali 设置动画?
- sql - 结合使用 case 子句 SQL Server 2014 从别名列中删除 Char 10、Char 13 字符
- javascript - 缺少数字算法超时错误 (JavaScript)