rxjs 5 publishReplay参考计数

rxjs 5 publishReplay参考计数,rxjs,rxjs5,Rxjs,Rxjs5,我不知道publishReplay().refCount()是如何工作的 例如(): 给出以下结果: 呼叫观察者A:5 observerB:5呼叫observerB:5 observerC:5 observerC:5调用observerC:5 观察者:5观察者:5观察者:5呼叫观察者:5 1) 为什么observer b、C和D被多次调用 2) 为什么“通话”打印在每一行上,而不是在行的开头 另外,如果我调用publishReplay(1).refCount(),它将分别调用observer b

我不知道
publishReplay().refCount()
是如何工作的

例如():

给出以下结果:

呼叫观察者A:5

observerB:5呼叫observerB:5

observerC:5 observerC:5调用observerC:5

观察者:5观察者:5观察者:5呼叫观察者:5

1) 为什么observer b、C和D被多次调用

2) 为什么“通话”打印在每一行上,而不是在行的开头

另外,如果我调用
publishReplay(1).refCount()
,它将分别调用observer b、C和D两次


我所期望的是,每个新的观察者只接收一次值5,而“call”只打印一次。

这种情况发生是因为您使用的是
publishReplay()
。它在内部创建一个
ReplaySubject
的实例,该实例存储所有经过的值

由于您使用的是
Observable.create
,您在其中发出一个值,然后每次调用
source.subscribe(…)
时,您都会在
ReplaySubject
中向缓冲区追加一个值

您不会在每行的开头打印
call
,因为是
ReplaySubject
在您订阅时首先发出缓冲区,然后订阅源:

有关实施详情,请参阅:


当使用
publishReplay(1)
时,同样适用。首先,它从
ReplaySubject
发出缓冲项,然后从
observer发出另一项

通常情况下:
refCount
意味着只要至少有一个订户,流就是热/共享的-但是,当没有订户时,流是重置/冷的

这意味着,如果您想绝对确保任何操作都不会执行一次以上,则不应使用
refCount()
,而应简单地使用
connect
流将其设置为热

另请注意:如果在
observer.next(5)之后添加
observer.complete()
您还将获得预期的结果


旁注:您真的需要在这里创建自己的自定义
Obervable
?在95%的情况下,现有的操作符足以满足给定的用例。

publishReplay(x).refCount()
组合起来执行以下操作:

  • 它创建了一个
    ReplaySubject
    ,它最多可以回放x次排放。如果未定义x,则它将重放整个流
  • 它使用refCount()操作符使这个
    ReplaySubject
    多播兼容。这导致并发订阅接收相同的排放
您的示例中包含了一些问题,这些问题影响了它们如何协同工作。请参阅以下修订的代码段:

var state=5
var realSource=Rx.Observable.create(观察者=>{
log(“创建昂贵的基于HTTP的排放”);
observer.next(state++);
//observer.complete();
return()=>{
console.log('从源取消订阅')
}
});
var源=可观测的接收值(“”)
.do(()=>console.log('stream subscribed'))
.ignoreElements()
.concat(realSource)
.do(null,null,()=>console.log('stream completed'))
.publishReplay()
.refCount()
;
subscription1=source.subscribe({next:(v)=>console.log('observerA:'+v)});
订阅1.取消订阅();
subscription2=source.subscribe(v=>console.log('observerB:'+v));
订阅2.取消订阅();
subscription3=source.subscribe(v=>console.log('observerC:'+v));
订阅3.取消订阅();
subscription4=source.subscribe(v=>console.log('observerD:'+v));

唯一相关的答案
var source = Rx.Observable.create(observer =>  {
  console.log("call"); 
  // expensive http request
  observer.next(5);
}).publishReplay().refCount();

subscription1 = source.subscribe({next: (v) => console.log('observerA: ' + v)});
subscription1.unsubscribe();
console.log(""); 

subscription2 = source.subscribe({next: (v) => console.log('observerB: ' + v)});
subscription2.unsubscribe();
console.log(""); 

subscription3 = source.subscribe({next: (v) => console.log('observerC: ' + v)});
subscription3.unsubscribe();
console.log(""); 

subscription4 = source.subscribe({next: (v) => console.log('observerD: ' + v)});
subscription4.unsubscribe();