首页 文章

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

提问于
浏览
0

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

Question

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

这只是简约的例子,如果你有一些问题或我的解释很差,请在评论中告诉我,我会更新我的问题 . 谢谢

3 回答

  • 2

    你可以使用takeUntill Operator . 它需要第二个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

  • -1
  • -3

    您可以使用 first 运算符:

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

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

    请注意,您应确保在完成之前至少发出一次,否则将引发错误 . 如果您无法确保这一点,则可以使用 take(1) 代替:

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

    请注意,这实际上并不直接修改 userData observable,因此其他订阅将继续发送,无论如何 . 这是因为rxjs中的运算符不会修改observable,而是返回一个新的observable .

相关问题