RxJs:Observable有状态吗?

时间:2017-11-18 16:24:52

标签: rxjs reactive

我问这个是因为我尝试了以下代码:

//RxJs v5.5.2; NodeJs v7.10.1
var Rx = require('rxjs/Rx'); 
var observable = Rx.Observable.of(1,2,3);

var sub = observable.subscribe(console.log);
var sub1 = observable.subscribe(console.log);

输出1 2 3 1 2 3(省略新行)。

然而,正如RxJs的文档所说,Observable是一个流,那么为什么第二个订阅获得所有值?我的理解是,在第一次订阅之后,observable已经完成并且作为流,它应该永远不会产生它已经发出的值。

我误解了什么吗?

1 个答案:

答案 0 :(得分:1)

从上面引用的文章Hot vs Cold Observables

  

Observables只是功能!   Observable是将观察者绑定到生成器的函数。而已。它们不一定设置生成器,它们只是设置一个观察者来监听生产者,并且通常返回一个拆除机制来移除该监听器。订阅行为是像函数一样“调用”observable并将其传递给观察者的行为。

因此,observable只是生产者和观察者之间的管道,生产者可以(经常)将状态“烘焙”。

试图证明示例Rx.Observable.of(1,2,3)中的某个地方有一个制作人有点困难。

Observable.of的来源是

export const of = ArrayObservable.of;

和ArrayObservable.of

static of<T>(...array: Array<T | IScheduler>): Observable<T> {

所以在这种情况下,扩展运算符是生成器array是传递给Observable的状态。

我找不到传播运算符的来源,但是这个引用es6-equivalents-in-es5#spread-operator给出了以下es5等价物

var _toArray = function (arr) {
  return Array.isArray(arr) ? arr : [].slice.call(arr);
};

function add(a, b) {
  return a + b;
}

var nums = [5, 4];
console.log(add.apply(null, _toArray(nums)));

假设上面的_toArray()是一个公平的传播近似值,我们可以说传播本质上是一个生产函数。

那么,Rx.Observable.of(1,2,3)是否有州?我们可以争辩是的,因为声明包含了州,但是在等效的

const nums = [1,2,3]
const src = Rx.Observable.of(...nums)

我们可以看到状态实际上是可观察的外部。


怎么样热?

热观察者有一个生产者没有按要求再现它的价值,例如事件。

因此,当生产者很热时,观察者在设置管道之前就没有“记住”状态(即订阅发生时),所以生产者的状态再次不是可观察的。

console.clear()

const eventEmitter = new EventEmitter();
var source = Rx.Observable.fromEvent(eventEmitter, 'data')

eventEmitter.emit('data', 1);
eventEmitter.emit('data', 2);
source.subscribe(x => console.log('subscription', x))
eventEmitter.emit('data', 3);
eventEmitter.emit('data', 4);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/EventEmitter/5.2.4/EventEmitter.js"></script>