我有一个抽象服务类,该类基本上处理具有不同参数的查询的预订。作为订阅者,您只希望订阅一次,而不必担心查询的参数是否已更改。
export abstract class BroadcastService<T>{
results: Observable<T[]>;
fb: FirebaseService;
config: ConfigurationService;
protected constructor (fb: FirebaseService, config: ConfigurationService) {
this.fb = fb;
this.config = config;
this.results = this.broadcaster.asObservable();
this.updateSubscription();
}
protected broadcaster: Subject<T[]> = new Subject();
protected params: any;
protected currentQuerySubscription: Subscription;
protected resultList: any[];
protected updateSubscription() {
if (this.paramsRequired() && this.params == null) {
return;
}
if (this.currentQuerySubscription != null) {
this.currentQuerySubscription.unsubscribe();
}
this.currentQuerySubscription = this.resultsQuery(this.params).subscribe((objs) => {
this.broadcaster.next(objs);
this.resultList = objs;
});
}
setParams(params: any) {
this.params = params;
this.updateSubscription();
}
protected abstract resultsQuery(params: any): Observable<T[]>;
protected abstract paramsRequired(): boolean;
}
这基本上是做什么的,另一个组件可以订阅结果。其他组件可以更改resultsQuery的参数,而不会强迫现有订阅者重新订阅,因为它们对主题的订阅不会被破坏。仅在内部,如果参数已更新,则对旧查询的订阅将被转储,并且该类在内部对新查询进行订阅,并开始推送这些结果。
resultsQuery的示例如下所示:
protected resultsQuery(params: any): Observable<TreeNodeDocument[]> {
return this.afs.collection<TreeNodeDocument>(
this.resolveCustomer(), ref =>
ref.where('someId', '==', params['someId'])).valueChanges();
}
查询是非常标准的,只返回我们感兴趣的一组可观察到的节点。afs的类型为AngularFirestore(我正在使用的库)。
现在问题如下:我unsubscribe()
的处理程序被立即调用时有1个结果(错误),然后立即被调用又有17个结果(正确)。
如果再次更改参数,我将得到1个结果(错误),然后立即获得24个结果(正确)。
如果我取消注释整个区块
this.resultsQuery(this.params).subscribe
这不再发生,我只得到正确的结果(而不是中间的错误1结果调用)。当然,这很糟糕,因为现在,如果Firebase中的某些内容发生更改,则处理程序将被多次调用,因为我不会破坏旧的订阅。
我的问题是我现在想念的是什么......或对此行为的解释是什么?