Rxjs 如何强制publishReplay()重新订阅?
我对RxJS非常陌生,以下是我的故事。我想要一个可观察的“会话”,这样新订阅者将始终获得当前会话,然后获得所有新会话(如果可以)。所以我写了这样的东西: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
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是共享的。