为事件监听正确重构嵌套订阅

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

我有一个特殊的情况,通常使用“switchMap”来避免嵌套订阅并不能解决问题。

我发现了这段使用嵌套订阅的代码,并想重构它。

this.eventService.get(ProductDetailsPageEvent)
  .pipe(takeUntil(this.destroy$))
  .subscribe((event) => {
    combineLatest([
      this.getCurrentProduct(),
      this.getCurrentPage(),
    ])
      .pipe(first())
      .subscribe(([product, page]) => {
        track(product,page,event);
      });
  });

此代码确保每当用户导航到产品详细信息页面(触发 ProductDetailsPageEvent)时(并且只有在那时!)都会触发某些跟踪操作。

我想重构这段代码并尝试避免嵌套订阅

this.eventService.get(ProductDetailsPageEvent)
  .pipe(
    takeUntil(this.destroy$),
    switchMap((event) =>
      combineLatest([
        of(event),
        this.getCurrentProduct(),
        this.getCurrentPage(),
      ])
    ),
    first()
  ).subscribe(([event, page, product]) =>{
      track(product,page,event);
    }
  );

它第一次工作正常(注意“first()”链运算符),但每次访问 PDP 的其他尝试都不再触发“track”方法。 如果我删除“first()”操作符,就会遇到问题,即使我离开 PDP,也会触发“track”方法,导致控制台错误,因为没有当前产品可供获取...

如何在不诉诸嵌套订阅的情况下解决这个困境? 如何确保仅在每次触发新的 PDP 事件时检索页面和产品可观察对象?

angular memory-leaks rxjs-observables spartacus-storefront
1个回答
0
投票

您的代码运行得很好,但是当组件被销毁时,我们需要取消订阅。否则它会不断监听事件并在应用程序使用过程中逐渐堆积,最终导致内存泄漏。如果这样做,则不需要

first
运算符。

作为最佳实践,始终将您的订阅添加到订阅中,并在组件销毁时取消订阅。

private sub = new Subscription();

this.sub.add(
 this.eventService.get(ProductDetailsPageEvent)
  .pipe(
    takeUntil(this.destroy$),
    switchMap((event) =>
      combineLatest([
        of(event),
        this.getCurrentProduct(),
        this.getCurrentPage(),
      ])
    ),
  ).subscribe(([event, page, product]) =>{
      track(product,page,event);
    }
  )
);
...

...
ngOnDestroy() { 
    this.sub.unsubscribe();
}
© www.soinside.com 2019 - 2024. All rights reserved.