【发布时间】:2020-11-02 13:32:50
【问题描述】:
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) 并保留最后一个值,当有下游订阅者时,发出最后一个值以及任何未来的值。
如果我理解正确,会发生什么情况:如果第一个下游订阅者晚于主题源中的第一个值,则第一个值会丢失,因为那时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);
}
【问题讨论】:
-
您可以尝试删除
.asObservable()吗?我认为那里失去了价值 -
为什么不使用behaviourSubject?它将当前值发送给任何新订阅者:learnrxjs.io/learn-rxjs/subjects/behaviorsubject
-
@QuentinFonck 因为我不想指定初始值,因为任何值都是错误的。另外,如果您查看我的第二个代码 sn-p,我最终用
ReplaySubject解决了这个问题,但问题是shareReplay解决方案有什么问题。