使用 publishReplay 时出现意外的排放
基于一个问题 。以下代码段不会缓存预期的发射并阻止进一步的呼叫。相反,它会为每个订阅重新订阅 realSource 。
var state = 5
var realSource = Rx.Observable.create(observer => {
console.log("creating expensive HTTP-based emission");
observer.next(state++);
// observer.complete(); //absent on purpose
return () => {
console.log('unsubscribing from source')
}
});
var source = realSource
.do(null, null, () => console.log('stream completed'))
.publishReplay()
.refCount();
subscription1 = source.subscribe({next: (v) => console.log('observerA: ' + v)});
subscription1.unsubscribe();
subscription2 = source.subscribe(v => console.log('observerB: ' + v));
subscription2.unsubscribe();
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.1.0/Rx.js"></script>
运行此代码段时,我们可以清楚地看到它没有为 Observer B 发出重复值,实际上它为每个订阅创建了新的排放量。怎么会?
在下一次订阅发生之前,每个订阅都会被取消订阅。这有效地使 refCount 减少到零,没有进行多播。
问题在于 realSource
流未完成的事实。因为我们不是多播,所以下一个订户通过 ReplaySubject 获得一个新的 realSource
实例,并且新的排放量与之前已经排放的排放量一起被预先添加。