angular - refCount off 的 rxjs shareReplay 在第一个下游订阅者之前不会订阅源

标签 angular rxjs

export class DataService {
  private readonly dataSubject: Subject<Data> = new Subject();

  public readonly myData$: Observable<Data>;

  constructor() {
    this.myData$ = this.dataSubject.asObservable().pipe(
      shareReplay({
        bufferSize: 1,
        refCount: false,
      }),
    );
    // this would solve the problem, but is an ugly workaround
    // this.myData$.subscribe();
  }

  update(data: Data) {
    this.dataSubject.next(data);
  }

有一个全局单例DataService,它应该为应用程序的各个部分提供特定的数据。当消费者订阅时,他们应该立即收到最后的值,以及将来的新值。

我的理解如下:如果我添加如上所示的 shareReplay ,并关闭 refCounting,它将订阅其上游可观察对象(即 dataSubject 在这种情况下)立即并保留最后一个值,当有下游订阅者时,发出最后一个值以及任何 future 的值。

如果我理解正确的话,会发生什么:如果第一个下游订阅者晚于主题源中的第一个值,那么第一个值就会丢失,因为此时 shareReplay 还没有订阅了该主题,因此它没有收集之前的值。如果我立即添加下游订阅者,就可以解决问题,但这有点难看。

我能够通过下面的解决方法解决我的问题,该解决方法更好一些,我将重播功能移至主题本身,这样无论订阅者如何,它都已经保留了最后的值。但仍然想知道我可能错过了 shareReplay 的工作原理,或者我在上面的代码中是否犯了错误。

export class DataService {
  private readonly dataSubject: Subject<Data> = new ReplaySubject();

  public readonly myData$: Observable<Data>;

  constructor() {
    this.myData$ = this.dataSubject.asObservable().pipe(
      share(),
    );
  }

  update(data: Data) {
    this.dataSubject.next(data);
  }

最佳答案

当使用Subject时,如果next发生在subscribe之前,那么该值就会丢失。所以新订阅者无法获得最后的值。因此,建议使用 ReplaySubjectBehaviorSubject 来避免丢失这样的值。

回答实际问题,如 this article 中所述。关于shareReplay:

refCount: false means that upon first subscription to ReplaySubject it will subscribe to Source

不,它不会立即订阅。

关于angular - refCount off 的 rxjs shareReplay 在第一个下游订阅者之前不会订阅源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64646566/

相关文章:

c# - Angular2+ C# Web Api - 服务器端保存错误时间的日期时间

Angular2 - NgSwitch 中的模板引用

Angular Schematics 相对路径

javascript - 将 JS 文件导入 Ionic/Angular 2

javascript - Angular 8 在异步调用链之后返回可观察的

jquery - 如何从 jQuery 调用 Angular 方法

javascript - 使用 RxJS 将事件排队,每 350 毫秒触发一次

javascript - 转换 RxJS 5 Rx.Observable.timer(3000).mapTo({ id : 1 }) to RxJS 6?

javascript - 为什么 setTimeout() 使我的应用程序滞后,而 Rxjs timer().subscribe(...) 却没有?

javascript - 使用 takeUntil 模式取消订阅 Observables 时是否需要完成 Subject?