我有一个方法,可以分派一个动作,然后触发一个效果,然后触发一个服务,该服务将捕获/处理触发动作的错误。
我的问题是,当我分派操作时,服务上的错误处理程序将更新状态,但当我记录状态时,它仍处于旧状态。但是,当我订阅时,在 ngOnInit 上,状态已更新。我不熟悉流程,因为它有 rxjs,但我想如果我能让调度像承诺一样工作,那么我可以等待它,然后在完成后执行一个方法。
这是在 ngOnInit 上触发的代码:
setupFailedAddToCartStatus() {
combineLatest(
this.store.select(getAddToCartFailedStatus),
this.store.select(getAddToCartFailedMsg)
)
.pipe(
map(
([addToCartFailedStatus, addToCartFailedMsg]: [boolean, string]) => {
console.log('checkout.component - NgOninit - line: 385');
this.addToCartFailedStatus = addToCartFailedStatus;
this.addToCartFailedMsg = addToCartFailedMsg;
this.addToCartFailedStatus$.next(addToCartFailedStatus);
this.addToCartFailedMsg$.next(addToCartFailedMsg);
console.log({ addToCartFailedStatus, addToCartFailedMsg });
}
)
)
.subscribe();
}
这是触发调度操作并最终触发服务的代码。
addToCart() {
combineLatest(
this.store.select(getAddToCartFailedStatus),
this.store.select(getAddToCartFailedMsg),
this.product$,
this.variantId$,
this.specTemplateStatusAndValue$.pipe(
map((statusAndValue) => statusAndValue.value)
)
)
.pipe(
takeUntil(this.unsubscribe$),
first(),
flatMap(
([
addToCartFailedStatus,
addToCartFailedMsg,
product,
variantId,
specTemplateValue
]) => {
this.store.dispatch( <-----------this is the part where the action is being executed, but the logs below this method will be triggered first before the state can be updated.
this.checkoutActions.addToCart(
variantId,
product.normal_product ? 1 : 1,
specTemplateValue,
[]
)
);
console.log(
addToCartFailedStatus,
'checkout.component - addToCart - line: 1415'
);
if (addToCartFailedStatus) return of(null);
console.log('checkout.component - addToCart - line: 1417');
// return this.router.navigate(['/checkout', 'cart']);
return of(addToCartFailedStatus);
}
)
)
.subscribe(() => {
console.log(
this.addToCartFailedStatus$.value,
'checkout.component - addToCart - line: 1433'
);
if (this.addToCartFailedStatus$.value) return of(null);
console.log(
this.addToCartFailedStatus$.value,
'checkout.component - addToCart - line: 1435'
);
// return this.router.navigate(['/checkout', 'cart']);
});
}
日志:
正如您在日志中看到的那样,第 390 行在组件初始化时被触发,这是预期的。
但是在初始化之后,单击一个按钮,然后第 1415、1417、1433 和 1435 行将以旧状态运行,而不是更新后的状态。
更新后的状态可以在第 390 行看到,这是由 ngOninit 设置的。
我想要实现的是运行这段代码:
this.store.dispatch(
this.checkoutActions.addToCart(
variantId,
product.normal_product ? 1 : 1,
specTemplateValue,
[]
)
);
API/服务完成后,应运行第 1415、1417、1433 和 1435 行。
对您的问题的简短且完全无用的答案:
console.log(
addToCartFailedStatus,
'checkout.component - addToCart - line: 1415'
);
此代码始终记录
false
的原因是因为在 first()
之前有 flatmap
运算符。 this.store.select(getAddToCartFailedStatus),
显然第一次返回false
,因为你甚至还没有尝试向购物车添加东西,然后这个流将不会有第二个结果。
所以,您的评论
... but the logs below this method will be triggered first before the state can be updated.
是不正确的。日志按预期触发,状态可能此时已经是最新的,但您不会看到它。
更长的答案(不知何故让你失望)是:我强烈建议你再次阅读有关可观察量、RxJs 和 NgRx 的内容,因为从很多角度来看,你当前的实现确实很混乱。例如,您如何期望
addToCartFailedStatus
不是 false
?我的意思是,即使dispatch
保证同步执行并立即更新状态(事实并非如此),这个变量应该如何更新?另外,为什么你决定执行一个操作并立即处理其执行结果? NgRx 是反应式的,不能保证状态会立即更新。