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
,并关闭 refCount
ing,它将订阅其上游可观察对象(即 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
之前,那么该值就会丢失。所以新订阅者无法获得最后的值。因此,建议使用 ReplaySubject
或 BehaviorSubject
来避免丢失这样的值。
回答实际问题,如 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/