Rxjs 如何强制publishReplay()重新订阅?

Rxjs 如何强制publishReplay()重新订阅?,rxjs,reactive-programming,rxjs5,Rxjs,Reactive Programming,Rxjs5,我对RxJS非常陌生,以下是我的故事。我想要一个可观察的“会话”,这样新订阅者将始终获得当前会话,然后获得所有新会话(如果可以)。所以我写了这样的东西: var session = Rx.Observable.from([0,1,3]) .do(x => console.log("Useful job")) .publishReplay(1) .refCount(); var subscr1 = session.subscribe( x => { console

我对RxJS非常陌生,以下是我的故事。我想要一个可观察的“会话”,这样新订阅者将始终获得当前会话,然后获得所有新会话(如果可以)。所以我写了这样的东西:

var session = Rx.Observable.from([0,1,3])
  .do(x => console.log("Useful job"))
  .publishReplay(1)
  .refCount();

var subscr1 = session.subscribe( x => {
    console.log("sub1 = " +x)
    //subscr1.unsubscribe();
})

console.log("Completed");
subscr1.unsubscribe();

session.subscribe( x => {
  console.log("sub2 = " +x)
});
输出为:

Useful job
sub1 = 0
Useful job
sub1 = 1
Useful job
sub1 = 3
Completed
sub2 = 3

为什么sub2订阅时没有有用的作业?我想天气会很冷

publishReplay()的第一个参数是它将重播的项目数,因此如果您知道总是只能使用3个,则可以使用
.publishReplay(3)

如果要重放整个序列,可以首先使用
toArray()
收集其所有项,将数组存储在
ReplaySubject
中,然后将数组展平为单个值

var session = Rx.Observable.from([0,1,3])
  .toArray()
  .publishReplay(1)
  .refCount()
  .concatAll();
请注意,
toArray()
在其源代码完成之前不会发出任何消息

编辑:我知道现在有什么问题了

您的方法是正确的,但问题在于可观察的
中的
publishReplay()中使用的主题。源可观测对象发出三项并发送
complete
通知。当受试者收到
完成
错误
通知时,它会将自身标记为
已停止
,并且不会再提交任何项目。这就是你的例子中发生的事情

如果您在不发送
complete
的情况下手动发送值,它将按照您的预期工作

// var session = Rx.Observable.from([0,1,3])
var session = Rx.Observable.create(subscriber => {
    subscriber.next(0);
    subscriber.next(1);
    subscriber.next(3);
  })
  .do(x => console.log("Useful job"))
  .publishReplay(1)
  .refCount();
这将打印到控制台:

Useful job
sub1 = 0
Useful job
sub1 = 1
Useful job
sub1 = 3
Completed
sub2 = 3
Useful job
sub2 = 0
Useful job
sub2 = 1
Useful job
sub2 = 3

看到同样的问题:

我终于找到了解决办法

将.publishReplay(1)替换为.multicast(()=>new Rx.ReplaySubject(1))。所以基本上我用一个主题工厂来代替一个主题


然后它就如预期的那样工作了。所以当每个人都退订时,天气变得绝对寒冷。

对不起,这只是一个样本。最初的“会话”实际上相当复杂。它连接到EventSource,做很多事情。然后发射“会话”对象。在某些时候,它可以重新连接并发出“新会话”对象。通常,它仅在“注销事件”时结束。现在在下一个“登录”事件中,我希望它重复第二次重新连接时可以观察到的会话。“不是这样的。”诺雷霍夫:你能做一个模拟这个问题的演示吗?我可能不知道事件的顺序是什么,相反,什么是
会话
。想象一下Rx.Observable.from([0,1,3])是一个很少发出新会话的可观察对象。在某个时刻,会话“3”变为非活动状态。Second observable接收到“3”,而我希望会话observable被重新启动。类似shareReplay的操作应该执行。我恐怕没有遵循。会话本身是可观察的吗?因此,您没有使用
Rx.Observable.from([0,1,3])
而是使用可观察发射的Observable?请注意,现在每个订阅者都有自己的
ReplaySubject
(与
.publishReplay(1)一样,
ReplaySubject
不是在所有订阅者之间共享的)
@martin不,他们没有。每个新订户都将收到传递的最后一个值,这意味着ReplaySubject是共享的。