我有一个特殊的情况,通常使用“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 事件时检索页面和产品可观察对象?
您的代码运行得很好,但是当组件被销毁时,我们需要取消订阅。否则它会不断监听事件并在应用程序使用过程中逐渐堆积,最终导致内存泄漏。如果这样做,则不需要
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();
}