关于javascript:冷可观察与重播主题之间的区别?

Difference between Cold observable and Replay subject?

我从文档中看到:

Cold Observables从开始到每个Observer发出整个值序列。

ReplaySubject向观察者发出源Observable发出的所有项目,无论观察者何时订阅。

那么这两个概念有什么区别?

谢谢


一旦ReplaySubject订阅了源可观察对象,该源就开始发射,并且ReplaySubject成为热观察对象。从订户的角度来看,预订ReplaySubject可能并不明显,因为它获得了所有先前发出的值。但是ReplaySubject仅预订一次源,因此主题能够将这些源值重新发送给以后的订户的唯一方法是缓存这些值。

因此不同之处在于,当直接订阅可观察的源时,源重新发出每个订户的值,而使用ReplaySubject订阅源,则源仅发出一次,并且该主题的任何订户都获得那些缓存的值。

考虑以下来源可观察

1
2
3
4
5
6
7
var source = Rx.Observable.create(function(subscriber) {
  for (var i = 0; i < 2; i++) {
    subscriber.onNext(i);
    console.log("onNext:" + i);
  }
  subscriber.onCompleted();
});

如果我们直接订阅源,则应该看到两次日志集

1
2
3
4
5
6
source.subscribe(function(value) {});
source.subscribe(function(value) {});
//onNext: 0
//onNext: 1
//onNext: 0
//onNext: 1

使用ReplaySubject,一旦订阅了源,源便开始发射,从而使热对象开始发射并缓存值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var subject = new Rx.ReplaySubject();
source.subscribe(subject);
setTimeout(function() {
  console.log('subscribe subject');
  subject.subscribe(function(value) { console.log('subscriber')});
  subject.subscribe(function(value) { console.log('subscriber')});
}, 100);
//onNext: 0
//onNext: 1
//subscribe subject
//subscriber
//subscriber
//subscriber
//subscriber

在这里,您可以看到源在被主题订阅后开始发射。但是,对该主题的任何订阅都不会导致源重新发射,就像前面的示例一样,每个新订阅者都导致源重新发射。


为了进一步详细说明先前的答案,我建议您看一下另一个SO问题,该问题应该有助于使事情变得更清楚:冷热观测值:是否存在冷热运算符?

是的,如果我们谈论replay(),即不带任何参数,则重放和冷可观察的行为看起来相似。但是,它们并不相同。

例如,

1
2
3
4
5
6
cold$ = Rx.Observable.just(1).map(function(){return Math.random();});
coldReplay$ = cold$.replay();
cold$.subscribe(function(x){console.log('cold:' + x);})
cold$.subscribe(function(x){console.log('cold:' + x);})
coldReplay$.subscribe(function(x){console.log('replay:' + x);});
coldReplay$.subscribe(function(x){console.log('replay:' + x);});

当您订阅重播时以及直接订阅冷可观察时,将永远不会为您提供相同的值。

从前面的链接中应该清楚为什么如此。订阅冷的可观察节目时,您将从第一个源开始,一直到订阅。重放时,您不会重新启动,重放已将发出的值保留在缓冲区中,并立即直接传递缓冲区中的值和新值。