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

时间:2017-02-21 14:29:38

标签: 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.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订阅时没有有用的工作?我希望它完全冷!

2 个答案:

答案 0 :(得分:1)

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

如果要重播整个序列,可以先使用ReplaySubject收集所有项目,将数组存储在var session = Rx.Observable.from([0,1,3]) .toArray() .publishReplay(1) .refCount() .concatAll(); 中,然后将数组展平为单个值。

toArray()

请注意Observable.from在源完成之前不会发出任何内容。

编辑:我现在看到了问题所在。

您的方法是正确的,但问题出在publishReplay()complete内使用的主题中。源Observable发出三个项目并发送complete通知。当主题收到errorstopped通知时,它会将自己标记为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

打印到控制台:

output[k] = output.append(GPS[1,i], GPS[0,i], Data[1,j])

查看同一问题:Rx.Subject loses events

答案 1 :(得分:1)

最后我找到了解决方案。

将.pultlishReplay(1)替换为.multicast(()=> new Rx.ReplaySubject(1))。所以基本上我用subjectFactory替换了一个主题。

然后它按预期工作。所以每个人取消订阅都会变得非常冷。