想象一下当您有一些Observable
包含实时变化的数据时的情况,如下例...
interface User {
name: string;
projectId: string;
dataThatChangesALotInRealTime: Object;
}
userData: Observable<User>
此userData
可观察值用于组件中以显示一些实时更改的数据。例如
<p>
{{ (userData | async)?.dataThatChangesALotInRealTime }}
</p>
现在,我想根据userData
中可观察到的当前数据向数据库中插入一些数据。这是功能
addToDatabase() {
let sub = this.userData.subscribe(data => {
this.exampleDatabase.doc(`test/${data.dataThatChangesALotInRealTime.id}`)
.add({ test: 'hello'})
sub.unsubscribe() // <- This
})
}
问题
这是取消订阅内部预订以避免多次插入数据库的正确解决方案吗?有其他/更好的方法吗?
这只是一个简单的示例,如果您有一些问题或我的解释不力,请在评论中让我知道,我将更新我的问题。谢谢
答案 0 :(得分:4)
您可以使用first
运算符:
this.userData.pipe(first()).subscribe(...);
这将在发出第一个值后自动完成(并因此取消订阅)。
请注意,在完成之前,请确保它至少发出一次,否则将引发错误。如果不能确保这一点,可以改用take(1)
:
this.userData.pipe(take(1)).subscribe(...);
请注意,这实际上并没有直接修改可观察的userData
,因此无论如何它的其他订阅都将继续发出。这是因为rxjs中的运算符不会修改可观察变量,而是返回一个新的可观察变量。
答案 1 :(得分:-3)
您可以使用takeUntill运算符。它以第二个Observable作为参数,它监视第二个Observable并在其发出值或终止后丢弃订阅。
export class TakeUntilCardComponent implements OnInit, OnDestroy {
message: string;
private unsubscribe$ = new Subject();
constructor(private upperCaseService: UpperCaseService) {}
ngOnInit() {
this.upperCaseService.getUpperCaseMessage()
.takeUntil(this.unsubscribe$)
.subscribe((message: string) => this.message = message);
}
ngOnDestroy(): void {
this.unsubscribe$.next();
this.unsubscribe$.complete();
}
}
这是功能全面的demo
如果您要引用它,还有一个非常好的博客! Don't unsubscribe