我正在通过以下查询通过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),
,这并不理想,因为时间会根据网络,标签数量等而变化。
不幸的是,我还没有找到一种解决方案,它在可观察项“完成”之后取消订阅数据流。
有没有办法在可观察到的“完成”之后退订,或停止发出值?
谢谢!
答案 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;
});
}