RxJS - 只订阅一次但不完成 Observable

Posted

技术标签:

【中文标题】RxJS - 只订阅一次但不完成 Observable【英文标题】:RxJS - subscribe only once but do not complete Observable 【发布时间】:2019-05-10 13:51:51 【问题描述】:

想象一下当你有一些 Observable 包含实时变化的数据时的情况,下面的例子......

interface User 
   name: string;
   projectId: string;
   dataThatChangesALotInRealTime: Object;


userData: Observable<User>

这个userData observable 在组件中用于显示一些实时变化的数据。例如

<p>
 (userData | async)?.dataThatChangesALotInRealTime 
</p>

现在我想根据userData observable 中的当前数据向数据库中插入一些数据。这是函数

addToDatabase() 
  let sub = this.userData.subscribe(data => 
     this.exampleDatabase.doc(`test/$data.dataThatChangesALotInRealTime.id`)
          .add( test: 'hello')
     sub.unsubscribe() // <- This
  )

问题

这是取消订阅内部订阅以避免多次插入数据库的正确解决方案吗?有没有不同/更好的方法来做到这一点?

这只是一个简单的例子,如果你有一些问题或者我的解释很差,请在 cmets 中告诉我,我会更新我的问题。谢谢

【问题讨论】:

【参考方案1】:

您可以使用first 运算符:

this.userData.pipe(first()).subscribe(...);

这将在第一个值发出后自动完成(因此取消订阅)。

请注意,您应该确保它在完成之前至少发出一次,否则会引发错误。如果您不能确保这一点,您可以改用take(1)

this.userData.pipe(take(1)).subscribe(...);

请注意,这实际上并没有直接修改userData observable,因此其他订阅它的人将继续发射。这是因为 rxjs 中的操作符不会修改 observable,而是返回一个新的 observable。

【讨论】:

我不想完成userData observable。我仍然想在组件中显示数据,并可能多次触发函数addToDatabase()... @Raold 它不会阻止你这样做。 “原始”的 observable 没有受到影响,因为操作符总是返回一个新的 observable。因此对 userData 的任何其他订阅都不会受到它的影响。 如果我理解正确,每当我使用 pipe 运算符时,它都会创建新的 observable? 是的,rxjs 在这方面使用了不变性,所以添加一个操作符并不会修改原来的 observable 而是返回一个新的。 @Raold 我已经添加了它。干杯。

以上是关于RxJS - 只订阅一次但不完成 Observable的主要内容,如果未能解决你的问题,请参考以下文章

了解 mqtt 订阅者 qos

取消订阅 Rxjs finalize 操作符

只订阅多个 FormControl(s) 一次

RxJS 等待订阅 Observable 完成

Angular中利用rxjs库的Subject多播解决在第一次订阅时进行初始化操作(如第一次订阅时从服务器获取数据)

RxJS 订阅永远不会结束