有没有办法在没有分配的情况下取消订阅 BehaviorSubject?
Is there a way to unsubscribe to a BehaviorSubject without assignment?
有时候我想订阅一个 observable 只是为了让一个 emit 触发额外的事件。例如,订阅路由中的查询参数,以便从发射中触发另一个事件——发射的值实际上并不重要。或者例如,如果我有一个 BehaviorSubject 并且需要根据对该主题的更改重新加载某些组件。在这些情况下,observable 并不意味着被模板使用,它们发出的值在很大程度上被忽略了。
理想情况下我会这样写:
ngOnInit() {
this.service.behaviorSubject.subscribe(
() => callLocalMethod()
)
}
问题在于,一旦组件被销毁,angular 不会取消订阅,这意味着每次初始化和销毁组件时,除了旧订阅之外,还会创建一个新订阅并发出来自 observable 的每个冗余订阅都被调用。在 OnDestroy 生命周期挂钩中取消订阅是不可能的(据我所知),因为订阅没有分配给 属性 - 但对于这个用例来说,将它分配给 属性 似乎是不必要的。
所以我最终要做的是为每个订阅创建一个 属性,即使 属性 永远不会被使用,将其分配给订阅,然后调用 unsubscribe()
当组件被销毁时。
这似乎真的是多余的 - 有更好的方法吗?使用异步管道处理订阅不是一种选择,而使用 EventEmitter 也不是一种选择,因为通常希望它表现得像一个热可观察对象。
您可以使用其他主题:
private destroy$ = new Subject();
constructor() {
obs$
// Ensures that we complete when the component is
// destroyed. Completing will automatically unsubscribe.
.takeUntil(this.destroy$)
.subscribe();
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
这样做的好处是它可以很好地扩展,因为无论您管理的订阅数量如何,样板文件只需要一次。
另请注意,ActivatedRouter实际上是在组件销毁时完成params
/ paramMap
,因此参数更改不需要手动取消订阅。
使用 takeWhile 你可以简单地使用一个布尔变量
private alive: boolean = true; //we use a variable
//All ours subscriptions are like
this.service.method()
.takeWhile(() => this.alive)
.subscribe(result => {...})
//in ngOnDestroy
public ngOnDestroy() {
this.alive = false;
}
有时候我想订阅一个 observable 只是为了让一个 emit 触发额外的事件。例如,订阅路由中的查询参数,以便从发射中触发另一个事件——发射的值实际上并不重要。或者例如,如果我有一个 BehaviorSubject 并且需要根据对该主题的更改重新加载某些组件。在这些情况下,observable 并不意味着被模板使用,它们发出的值在很大程度上被忽略了。
理想情况下我会这样写:
ngOnInit() {
this.service.behaviorSubject.subscribe(
() => callLocalMethod()
)
}
问题在于,一旦组件被销毁,angular 不会取消订阅,这意味着每次初始化和销毁组件时,除了旧订阅之外,还会创建一个新订阅并发出来自 observable 的每个冗余订阅都被调用。在 OnDestroy 生命周期挂钩中取消订阅是不可能的(据我所知),因为订阅没有分配给 属性 - 但对于这个用例来说,将它分配给 属性 似乎是不必要的。
所以我最终要做的是为每个订阅创建一个 属性,即使 属性 永远不会被使用,将其分配给订阅,然后调用 unsubscribe()
当组件被销毁时。
这似乎真的是多余的 - 有更好的方法吗?使用异步管道处理订阅不是一种选择,而使用 EventEmitter 也不是一种选择,因为通常希望它表现得像一个热可观察对象。
您可以使用其他主题:
private destroy$ = new Subject();
constructor() {
obs$
// Ensures that we complete when the component is
// destroyed. Completing will automatically unsubscribe.
.takeUntil(this.destroy$)
.subscribe();
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
这样做的好处是它可以很好地扩展,因为无论您管理的订阅数量如何,样板文件只需要一次。
另请注意,ActivatedRouter实际上是在组件销毁时完成params
/ paramMap
,因此参数更改不需要手动取消订阅。
使用 takeWhile 你可以简单地使用一个布尔变量
private alive: boolean = true; //we use a variable
//All ours subscriptions are like
this.service.method()
.takeWhile(() => this.alive)
.subscribe(result => {...})
//in ngOnDestroy
public ngOnDestroy() {
this.alive = false;
}