我问这个是因为我尝试了以下代码:
//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已经完成并且作为流,它应该永远不会产生它已经发出的值。
我误解了什么吗?
答案 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>