取消订阅和重新订阅后,Firebase Query或Observable在首次调用时产生错误结果

时间:2018-10-11 08:41:59

标签: angular firebase rxjs angularfire2

我有一个抽象服务类,该类基本上处理具有不同参数的查询的预订。作为订阅者,您只希望订阅一次,而不必担心查询的参数是否已更改。

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中的某些内容发生更改,则处理程序将被多次调用,因为我不会破坏旧的订阅。

我的问题是我现在想念的是什么......或对此行为的解释是什么?

0 个答案:

没有答案