可观察到的“完成”后退订

时间:2020-08-18 17:33:44

标签: angular firebase google-cloud-firestore rxjs angularfire2

我正在通过以下查询通过RxJS从Firebase接收数据:

getAppliedLocalTags() {
    this.tagSub = this.pageService
      .getTagsOnPage(this.workspaceId, this.currentPage.id)
      .pipe(
        switchMap((references) => from(references)),
        mergeMap((ref) => this.afs.doc(ref).snapshotChanges()),
        map((actions) => actions.payload.data()),
        scan((allTagData, tagData) => [...allTagData, tagData], [])
      )
      .subscribe((data) => {
        this.appliedTags = data;
      });
    // STOP THE SUB ONCE WE GET THE TAGS
    setTimeout(() => {
      console.log("un-subbed from tags");
      this.tagSub.unsubscribe();
    }, 2000);
  }

订阅时,this.appliedTags会填充来自数据库的所有“标签”。

在这种情况下,我只需要一次值。获得所有值后,我将退订,但是目前执行此操作的最佳方法是使用setTimeout(() => {}, 2000),,这并不理想,因为时间会根据网络,标签数量等而变化。

不幸的是,我还没有找到一种解决方案,它在可观察项“完成”之后取消订阅数据流。

有没有办法在可观察到的“完成”之后退订,或停止发出值?

谢谢!

1 个答案:

答案 0 :(得分:1)

这可以通过两种方式解决:

承诺方式:

getAppliedLocalTags() {
    this.tagSub = this.pageService
      .getTagsOnPage(this.workspaceId, this.currentPage.id)
    .pipe(
        switchMap((references) => from(references)),
        mergeMap((ref) => this.afs.doc(ref).snapshotChanges()),
        map((actions) => actions.payload.data()),
        scan((allTagData, tagData) => [...allTagData, tagData], [])
      )
    .toPromise().then((data) => {
            this.appliedTags = data;
        }).catch(err => {
        // handle error
    });
}

另一种方法是使用 take 运算符:

getAppliedLocalTags() {
    this.tagSub = this.pageService
      .getTagsOnPage(this.workspaceId, this.currentPage.id)
      .pipe(
        switchMap((references) => from(references)),
        mergeMap((ref) => this.afs.doc(ref).snapshotChanges()),
        map((actions) => actions.payload.data()),
        scan((allTagData, tagData) => [...allTagData, tagData], []),
        take(1) // This will emit only once then..
      )
      .subscribe((data) => {
        this.appliedTags = data;
      });
  }