首页 > 编程问答 >在我的 ngrx 效果中,switchMap 和其他运算符的区别

在我的 ngrx 效果中,switchMap 和其他运算符的区别

时间:2024-06-07 13:33:02浏览次数:21  
标签:angular rxjs ngrx

我有以下效果

 public SetProperTab$ = createEffect(
 public SetProperTab$ = createEffect(
    () => {
      返回 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);
                如果 (lastProductConfig) {
                  this.router.navigate([`/main/product-editor/${action.logicalProductId}/product-config/${lastProductConfig.ID}`]);
                }
              } else {
                this.router.navigate([`/main/product-editor/${action.logicalProductId}/product-config/${lastProductConfig.ID}`]);
              }
              返回 EMPTY;
            }),
          ),
        ),
      );
    },
    { dispatch: false }、
  );

它的基本功能是在用户点击 kendo-grid 列表后触发。然后,它会检查商店中是否已经有此类项目(及其大型数据集),如果没有,它将使用 ofType 运算符返回另一个管道,以确保 GetLogicalProductDetailsSuccess 成功完成(这发生在数据刚刚从后台下载之后),然后它将执行负责设置适当导航的逻辑......其余的并不重要。因为它正如预期的那样工作。

但在这种情况下,我不明白为什么将第一个操作符 switchMap 更改为 exasutMap 或 concatMap 会导致无法调用该效果。好吧--它被调用了,但只有一次(在选择第一个项目后),之后效果就不再有反应了,尽管下面的操作在用户点击列表项目时一直被派发......

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

我希望它的工作原理与 switchMap 相同......因为只在单击后执行一次操作......


問題在於你誤解了 exhaustMap concatMap 在這種情況下的運作方式。讓我們來分解一下每個運算子在這裡的行為,以及為什麼 switchMap 是正確的選擇:

1. switchMap

  • SetProperTab 操作被派發時, switchMap 訂閱 內部的 observable(在你的例子中,它是檢查商店或等待 GetLogicalProductDetailsSuccess 的邏輯)。
  • 如果在這個內部 observable 完成 之前 另一個 SetProperTab 操作被派發, switchMap 取消訂閱 先前的 observable,並使用新的 logicalProductId 開始一個新的 observable。
  • 這正是你想要的行為:每次點擊列表項時,你都想 取消 任何先前的導航嘗試,並根據最新的點擊開始一個新的導航。

2. exhaustMap

  • exhaustMap 也會在第一個 SetProperTab 操作時訂閱內部 observable。
  • 然而, 關鍵區別 在於:如果在內部 observable 完成 之前 收到另一個 SetProperTab 操作, exhaustMap 忽略 新的操作。它會等到當前的內部 observable 完成後,才會處理下一個 SetProperTab 操作。
  • 在你的情況下,這意味著只有第一次點擊會起作用。後續的點擊會被 exhaustMap 忽略,因為它還在等待先前的導航邏輯完成。

3. concatMap

  • concatMap exhaustMap 相似,它不會取消先前的 observable。
  • 但是,與 exhaustMap 不同的是, concatMap 排隊 所有收到的 SetProperTab 操作。當前一個內部 observable 完成後,它會按順序處理排隊的操作。
  • 在你的情況下,這可能會導致導航到錯誤的產品配置,因為它會按照點擊的順序處理導航,而不是總是導航到最新的點擊。

結論

因為你希望每次點擊列表項時都取消先前的導航並開始新的導航,所以 switchMap 是最適合這個情境的運算子。 exhaustMap concatMap 會導致你的效果無法按預期運作,因為它們會忽略或延遲後續的點擊事件。

标签:angular,rxjs,ngrx
From: 78588282

相关文章

  • Angular Material 18+ 高级教程 – CDK Drag and Drop
    前言         目录上一篇 AngularMaterial18+高级教程–MaterialTooltip下一篇 AngularMaterial18+高级教程–CDKTable想查看目录,请移步 Angular18+高级教程–目录喜欢请点推荐......
  • Angular Material 18+ 高级教程 – 大杂烩
    前言本篇记入一些AngularMaterial的小东西。 OverrideMaterialIconButtonSize参考:StackOverflow– Changesizeofmat-icon-button想overrideMaterialstyles有好几招可以用。第一招是overrideCSSvariables,这是最安全有效的方式,但是AngularMaterial不......
  • Angular 18+ 高级教程 – Coding Style Guide 编码风格
    前言Angular从v14开始大改特改,改最多的就是编码风格。以前偏向classfirst,@Decoratorfirst,mutablefirst。现在偏向functionfirst,immutablefirst。本篇主要是探讨v14后,尤其是Signal后的Angular编码风格,看看怎么写会比较合理舒服......
  • 深入解析Web前端三大主流框架:Angular、React和Vue
    Web前端三大主流框架分别是Angular、React和Vue。下面我将为您详细介绍这三大框架的特点和使用指南。Angular核心概念:组件(Components):组件是Angular应用的构建块,每个组件由一个带有装饰器的类、一个HTML模板、一个CSS样式表组成。组件通过输入(@Input)和输出(@Output)装饰......
  • Angular (四) | 创造属性指令-15
    1.简单属性指令的创建@Directive装饰器类似于@Component先创建选择器select创造函数里的实参为DOM元素值directive和component在ngMoudule里声明在一起2.获取元素属性值@Attribute在constructor获取属性值的参数3.输入属性可以通过指令的选择器直接获取参数值,但在......
  • Angular primeNg i18n 国际化多语言处理
    i18nAPI允许为组件全局设置翻译并与翻译库集成。PrimeNg官网相关地址详细步骤如下: 1:安装如下两个包。一个是翻译的一个是语音请求的npminstall@ngx-translate/core@ngx-translate/http-loader--save2:项目assets目录下创建en.json和zh.json两个文件或者更多国......
  • java+Angular+Nginx微服务架构+VUE 基于SaaS云部署、云计算的区域医院云HIS系统源码
    java+Angular+Nginx微服务架构+VUE基于SaaS云部署、云计算的区域医院云HIS系统源码HIS系统:可以根据医院规模、个性流程定制个性化程序;以临床工作为核心,方便医生的临床医疗行为,提高医疗服务质量,能提供临床专科数据分析系统,可用于医疗评估、生物医学研究、教育和医疗保健管理......
  • 界面组件Kendo UI for Angular教程 - 构建强大的PDF阅读器(二)
    如今当用户需要处理PDF文件时,通常不得不下载应用程序或者浏览器插件,控制用户如何与PDF交互并不是一件容易的事。如果我们提供PDF作为内容,用户可以下载它并使用浏览器或PDF本身提供的控件进行交互。然而,一些企业可能希望控制用户使用PDF的方式,以提供更好的体验或在某些条件下限制下......
  • Angular等了三年,那个她已经来了
    Angular生态丰富,功能强大,支撑了许多大型项目的开发。而且一直在前方等待着其他框架跟上。但是不得不直面的一个问题就是:“在等待其他框架跟上的这三年”,Angular在陆陆续续抛弃之前引以为豪的设计。又由于大量的历史包袱,这些设计变更又做得扭扭捏捏,做不到轻装上阵。比如NgModule之......
  • Angular多环境打包项目并发布到nginx运行
    1:官网下载稳定版本Nginx1.26.0  2:先跑起来看是否异常,如果没有跑起来我们可以检查分析nginx的log日志3:项目路径如下: 4:前端多环境简单测试配置 5:路由配置简单测试数据constroutes:Routes=[{path:'',redirectTo:'/home',pathMatch:"full"},{......