几个月后,我回到了最初的问题,并希望与此同时分享所获得的知识。我将使用以下代码作为说明支持(jsfiddle):
var ta_count = document.getElementById('ta_count');
var ta_result = document.getElementById('ta_result');
var threshold = 3;
function emits ( who, who_ ) {return function ( x ) {
who.innerHTML = [who.innerHTML, who_ + " emits " + JSON.stringify(x)].join("\n");
};}
var messages$ = Rx.Observable.create(function (observer){
var count= 0;
setInterval(function(){
observer.onNext(++count);
}, 1000)
})
.do(emits(ta_count, 'count'))
.map(function(count){return count < threshold})
.do(emits(ta_result, 'result'))
messages$.subscribe(function(){});
如答案之一所述,定义可观察对象将导致一系列回调和参数注册。数据流必须插入,并且可以通过subscribe
函数来完成。此后可以找到(为说明简化)的详细流程。
默认情况下,可观察值是冷的。订阅可观察项将导致订阅的上游链发生。最后的订阅导致执行一个函数,该函数将处理源并将其数据发送给其观察者。
该观察者依次向下一个观察者发出,导致下游数据流向下到接收器观察者。以下简化图示显示了两个订户订阅同一可观察项时的订户和数据流。
可以通过使用主题或通过multicast
运算符(及其派生形式,请参见下面的注释3)来创建热的可观察物。
在multicast
引擎盖下运营商利用一个主题,并返回一个可连接的可观察的。对操作员的所有订阅都将是对内部主题的订阅。当connect
被调用时,内部主体所预订的上游观察到的,和数据流下游。主体在内部操作订阅的观察者列表,并将传入的数据多播到所有订阅的观察者。
下图总结了这种情况。
最后,更重要的是要了解由观察者模式和运算符的实现引起的数据流。
例如,如果obs
很热,是hotOrCold = obs.op1
冷还是热?无论答案是:
- 如果没有订阅者
obs.op1
,则不会有数据流过op1
。如果有热点用户obs
,那obs.op1
将可能丢失数据
- 假设它
op1
不是一个类似于多播的运算符,则两次hotOrCold
订阅将会订阅两次op1
,并且来自的每个值obs
都会通过两次op1
。
注意事项:
- 此信息对于Rxjs v4应该有效。尽管版本5进行了相当大的更改,但大多数版本仍保持逐字记录。
- 取消订阅,错误和完成流程不表示,因为它们不在问题范围内。调度程序也没有考虑在内。除其他因素外,它们影响数据流的时序,但不影响数据流的方向和内容。
- 根据用于多播的主题类型,有不同的派生多播运算符:
Subject type | `Publish` Operator | `Share` operator
------------------ | --------------------------- | -----------------
Rx.Subject | Rx.Observable.publish | share
Rx.BehaviorSubject | Rx.Observable.publishValue | shareValue
Rx.AsyncSubject | Rx.Observable.publishLast | N/A
Rx.ReplaySubject | Rx.Observable.replay | shareReplay
更新:另请参见本·莱什(Ben Lesh)关于该主题的以下文章(在此和该处)。
关于主题的更多详细信息可以在另一个SO问题中找到:不同的RxJS主题的语义是什么?