假设我有很多包含这样结构的组件
ngOnInit() {
this.fb.user$.subscribe(data => {
if (data != null) {
//User is logged in
this.fb.afs.collection('col').doc(data.info).valueChanges().subscribe(info => {
this.info = info;
})
//Lots of other subscriptions following...
} else {
//User is logged out
}
})
}
用户注销后,会因为
而抛出Firebase权限异常this.fb.afs.collection('col').doc(data.info).valueChanges().subscribe(info => {
this.info = info;
})
不再允许订阅。
是否还有其他取消订阅所有Firebase订阅的方法,而无需将所有订阅手动推送到数组并在注销用户之前将其循环?
答案 0 :(得分:2)
也许通过takeUntil
运算符传递给每个运算符?
destroyed = new Subject();
destroyed$ = this.destroyed.asObservable();
constructor() {
resource1$.pipe(takeUntil(this.destroyed$)).subscribe(...);
resource2$.pipe(takeUntil(this.destroyed$)).subscribe(...);
resource3$.pipe(takeUntil(this.destroyed$)).subscribe(...);
}
ngOnDestroy() {
this.destroyed.next();
this.destroyed.complete();
}
takeUntil:发射值,直到提供可观察到的发射为止。
答案 1 :(得分:1)
首先,不建议在rxjs中使用嵌套订阅,对于这种逻辑,请使用switchMap
运算符。
要管理组件中的订阅,可以创建一个Subscription()
并在其上使用add
函数。请参见下面的示例:
import { Subscription } from 'rxjs';
@Component({...})
export class TestComponent implements OnInit, OnDestroy {
private readonly subscriptions = new Subscription()
ngOnInit() {
const firstSubscription = stream1$.subscribe(...);
const secondSubscription = stream2$.subscribe(...);
this.subscriptions.add(firstSubscription);
this.subscriptions.add(secondSubscription);
}
ngOnDestroy() {
this.subscriptions.unsubscribe();
}
这里还有一个更复杂的流管理示例:
import { Subscription, of } from 'rxjs';
import { switchMap, tap } from 'rxjs/operators';
@Component({...})
export class TestComponent implements OnInit, OnDestroy {
ngOnInit() {
const userSubscription = this.fb.user$.pipe(
switchMap(data => {
if (data) {
return this.fb.afs.collection('col').doc(data.info).valueChanges();
} else if (1 !== 2) { // for example
return this.anotherService.getDataById(data.id).pipe(
tap((cat) => {
// here you can also do some intermediate logic
this.cats = [cat];
})
)
}
// other things to be returned
// don't forget to olways pass something.
// if nothing matched, return default value
return of(null);
})
).subscribe(info => {
this.info = info;
});
this.subscriptions.add(userSubscription);
const anotherSubscription = this.anotherService.mockMethod.subscribe(() => /**
something */);
this.subscriptions.add(anotherSubscription);
}
ngOnDestroy() {
this.subscriptions.unsubscribe();
}
}
所以在这里您应该注意两件事:
与您的问题有关的内容:获取对订阅userSubscription
的引用(由.subscribe()
方法返回,并将其添加到组件subscriptions
中。然后在{{1 }}取消订阅该组件中的所有订阅。您可以根据需要添加任意数量。
不使用嵌套订阅。使用管道可以让您控制流并制作rxjs提供的许多很棒的功能。这是延迟,过滤,映射等等。我建议您学习更多有关扁平化策略(flatMap,switchMap,concatMap和haustMap)的信息。查看本文https://medium.com/@shairez/a-super-ninja-trick-to-learn-rxjss-switchmap-mergemap-concatmap-and-exhaustmap-forever-88e178a75f1b,并在那里观看视频。我认为这是对此主题的最佳解释。