我的ngrx效果中switchMap和其他操作符的区别

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

我有以下效果

  public SetProperTab$ = createEffect(
    () => {
      return this.actions$.pipe(
        ofType(actions.SetProperTab),
        switchMap((action) =>
          this.store$.select(selectors.GetHasLogicalProductInStore, { id: action.logicalProductId }).pipe(
            switchMap((hasLogicalProductInStore) => {
              if (hasLogicalProductInStore) {
                return of(true);
              } else {
                return this.actions$.pipe(ofType(actions.GetLogicalProductDetailsSuccess), take(1));
              }
            }),
            concatLatestFrom(() =>
              this.store$.select(selectors.GetProperSpecifiedLogicalProduct, { logicalProductId: action.logicalProductId }),
            ),
            concatMap(([_, properCurrent]) => {
              if (properCurrent?.ProductsLite.length) {
                const lastProductConfig: RestProductLiteEntity | undefined = properCurrent.ProductsLite.at(-1);
                if (lastProductConfig) {
                  this.router.navigate([`/main/product-editor/${action.logicalProductId}/product-config/${lastProductConfig.ID}`]);
                }
              } else {
                this.router.navigate([`/main/product-editor/${action.logicalProductId}/global`]);
              }
              return EMPTY;
            }),
          ),
        ),
      );
    },
    { dispatch: false },
  );

它的基本作用是在用户单击 kendo-grid 列表后触发。然后它检查此类项目(及其大数据集)是否已存储,如果没有,则返回带有 ofType 运算符的另一个管道,以确保 GetLogicalProductDetailsSuccess 完成(它发生在数据刚刚从后端下载之后),然后它执行负责设置的逻辑正确的导航和...其余的并不重要。因为它按预期工作。

但在这种情况下我无法理解为什么将第一个运算符 switchMap 更改为 exhasutMap 或 concatMap 会导致此效果无法调用。好吧 - 它只被调用一次(选择第一个项目后),之后效果不再做出反应,尽管下面的这个操作在用户点击列表项时一直被调度...

public onSelectedChanged(value: ID | null): void {
    if (value) {
      this.productEditorService.onSelectedChanged(value);
      this.store$.dispatch(SetProperTab({ logicalProductId: value.toString() }));
    }

我希望它的工作方式与 switchMap 相同...因为该操作在单击一次后仅调度一次...

angular rxjs ngrx
1个回答
0
投票

以下是简短的区别。

switchMap
取消对新外部值的当前内部订阅。

concatMap
将所有传入值放在一行中,完成当前值后,它将选择下一个值,如果传入大量外部值,这可能会积压。

exhaustMap
将忽略外部值,直到内部订阅完成。

现在根据您上面共享的代码,我认为您发出的是 concatLatestFrom,如果有更改,它将继续发出值,然后您稍后使用 concatMap 连接这些更改。

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