使用 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 实例,并且新的排放量与之前已经排放的排放量一起被预先添加。