componentDidMount() {
Promise.all([OfferCreationActions.resetOffer()]).then( () => {
OfferCreationActions.updateOfferCreation('viewOnly', true);
OfferCreationActions.updateOfferCreation('loadingOffer', true);
Promise.all([
OfferCreationActions.loadBarcodes(),
OfferCreationActions.loadBrandBarcodes(),
OfferCreationActions.loadBrands(),
OfferCreationActions.loadPayers(),
OfferCreationActions.loadSegments(),
OfferCreationActions.loadTactics(),
OfferCreationActions.loadStates(),
]).then(() => {
// let state settle before loading
setTimeout(() => {
OfferCreationActions.loadOffer(this.props.match.params.offerId);
}, 1500);
});
});
}
我正在开发一个React应用,该应用需要将一些数据预加载到状态中,然后加载一个更大的对象,该对象引用预加载的数据以映射某些字段。我遇到了一种竞争情况,在这种情况下,当我尝试执行映射时,仍会处理来自promise链的某些数据。我昨天添加了超时时间,但这对我来说并不是最好的解决方案。我对React还是很陌生,我们使用Reflux作为商店(如果有所作为)。有没有更好的方法来确保在发出呼叫之前,来自承诺的所有数据当前都已反映在状态中?我应该挂接到componentShouldUpdate并单独检查所有字段吗?
答案 0 :(得分:0)
实施此方法存在一个根本缺陷!您正在打破单向数据流的原理。这里有一些修复建议。
- 在单独的总体功能中进行副作用处理。
处理promise竞争条件是一个副作用(在React的UniFlow之外的某些东西)。因此,这不是与“反应”关联的问题。因此,作为onComponentDidMount的第一步,将此竞态条件逻辑委托给一个单独的动作。可能在“ resetOfferOverall()”内部执行此操作,我想这实际上就是正在发生的事情。
- 管理动作中的promise,并将有效载荷分配给商店
在您的代码中,可以保证在答应解决后将执行“ then”。但是,对这两个调用“ updateOfferCreation”的调用不属于此合同,因为它不在promise.all之内。也许他们还需要进入大规模的promise.all部分?可能需要在运行大量部分之前完成它们。只需重新检查一下即可!
resetOfferOverall() {
Promise.all([OfferCreationActions.resetOffer()]).then( () => {
.then( () => {
// These are not guaranteed to be completed before the next "then" section!
OfferCreationActions.updateOfferCreation('viewOnly', true);
OfferCreationActions.updateOfferCreation('loadingOffer', true);
//*****************************************
Promise.all([
OfferCreationActions.loadBarcodes(),
OfferCreationActions.loadBrandBarcodes(),
OfferCreationActions.loadBrands(),
OfferCreationActions.loadPayers(),
OfferCreationActions.loadSegments(),
OfferCreationActions.loadTactics(),
OfferCreationActions.loadStates(),
]).then(() => {
OfferCreationActions.loadOffer(offerId);
});
});
}
如果您希望在完成本节之前完成本节 所有人,请按如下所示更改您的代码。
async resetOfferOverall() {
Promise.all([OfferCreationActions.resetOffer()]).then( () => {
.then( () => {
await OfferCreationActions.updateOfferCreation('viewOnly', true);
await OfferCreationActions.updateOfferCreation('loadingOffer', true);
//await will stop code execution until the above async code is completed
Promise.all([
OfferCreationActions.loadBarcodes(),
OfferCreationActions.loadBrandBarcodes(),
OfferCreationActions.loadBrands(),
OfferCreationActions.loadPayers(),
OfferCreationActions.loadSegments(),
OfferCreationActions.loadTactics(),
OfferCreationActions.loadStates(),
]).then(() => {
//Now JS Guarantees that this call will not be called until everything above has been resolved!
OfferCreationActions.loadOffer(offerId);
});
});
}
- 确保您正在等待的操作正在返回承诺
无论等待什么方式,如果您没有真正返回调用本身内的相关诺言,您的代码将无法正常工作。让我们考虑加载条形码操作,并假设您使用axios来获取数据。
loadBarcodes(){
// This "return" right here is vital to get your promises to behave properly
return axios.get('https://localhost:8080/api/barcodes/').then((response) =>{
//DISPATCH_TO_STORE
});
//If you did not return this promise this call will resolve immediately
}
- 在组件上,注意relevent存储区。显示一个加载器,直到将有效负载加载到商店。
如您所见,依靠商店更新来显示数据,我们不会中断单向数据流。