RxJS combineLatest:如何在一次值更改后获取发射?

时间:2015-09-27 20:45:46

标签: reactive-programming rxjs

我正在尝试学习RxJS库。其中一个我不太了解的案例在this jsfiddle中有所描述(下面的代码也是如此)。

var A= new Rx.Subject();
var B= new Rx.Subject();

A.onNext(0);    

// '.combineLatest' needs all the dependency Observables to get emitted, before its combined signal is emitted.
//
// How to have a combined signal emitted when any of the dependencies change (using earlier given values for the rest)?
//    
A.combineLatest( B, function (a,b) { return a+b; } )
 .subscribe( function (v) { console.log( "AB: "+ v ); } );

B.onNext("a");  
A.onNext(1);

我想在" AB"日志记录。一个是将B改为" a" (A已经有值0)。另一种是将A改为1。

但是,只有订阅后发生的更改似乎很重要(即使A有值,因此可以计算合并结果)。

我应该使用" hot observables"为此,还是除.combineLatest之外的其他方法?

我在实际代码中的问题(比这个样本更大)是我需要在订阅之后进行单独的初始化,这会在两个单独的位置切换内容,而不是在前面清楚地显示初始值。

由于

1 个答案:

答案 0 :(得分:10)

我认为你误解了Subjects是如何运作的。 Subjects hot Observables。他们没有坚持价值观,所以如果他们收到的onNext没有订阅者,那么这个价值就会输给全世界。

您要查找的是BehaviorSubjectReplaySubject,它们都会保留过去的值,并将这些值重新发送给新订阅者。在前一种情况下,您始终使用初始值

构造它
//All subscribers will receive 0
var subject = new Rx.BehaviorSubject(0);

//All subscribers will receive 1
//Including all future subscribers
subject.onNext(1);

在后者中设置要为每个订阅重播的值的数量

var subject = new Rx.ReplaySubject(1);
//All new subscribers will receive 0 until the subject receives its 
//next onNext call
subject.onNext(0);

重写你的例子可能是:

var A= new Rx.BehaviorSubject(0);
var B= new Rx.Subject();    

// '.combineLatest' needs all the dependency Observables to get emitted, before its combined signal is emitted.
//
// How to have a combined signal emitted when any of the dependencies change (using earlier given values for the rest)?
//    
A.combineLatest( B, function (a,b) { return a+b; } )
 .subscribe( function (v) { console.log( "AB: "+ v ); } );

B.onNext("a");  
A.onNext(1);

//AB: 0a
//AB: 1a

另一方面,当然意识到这对你来说是全新的,在大多数情况下你不需要直接使用Subject因为它通常意味着你试图将Rx与你的安全纠缠在一起已知的范例。您应该问问自己,您的数据来自哪里?它是如何创建的?如果你对这些问题提出足够的要求,在你的事件链回到源代码后,你会发现有10个问题可能会有Observable封装。