如何在使用 NRGX 分派 Angular 操作后同步调用方法

问题描述 投票:0回答:1

我有一个方法,可以分派一个动作,然后触发一个效果,然后触发一个服务,该服务将捕获/处理触发动作的错误。

我的问题是,当我分派操作时,服务上的错误处理程序将更新状态,但当我记录状态时,它仍处于旧状态。但是,当我订阅时,在 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 行。

angular rxjs ngrx
1个回答
0
投票

对您的问题的简短且完全无用的答案:

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 是反应式的,不能保证状态会立即更新。

© www.soinside.com 2019 - 2024. All rights reserved.