RxJS-仅订阅一次,但不完成Observable

时间:2018-12-09 12:56:43

标签: angular rxjs observable subscription unsubscribe

想象一下当您有一些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
  })
}

问题

这是取消订阅内部预订以避免多次插入数据库的正确解决方案吗?有其他/更好的方法吗?

这只是一个简单的示例,如果您有一些问题或我的解释不力,请在评论中让我知道,我将更新我的问题。谢谢

2 个答案:

答案 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

相关问题