我正在尝试学习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
之外的其他方法?
我在实际代码中的问题(比这个样本更大)是我需要在订阅之后进行单独的初始化,这会在两个单独的位置切换内容,而不是在前面清楚地显示初始值。
由于
答案 0 :(得分:10)
我认为你误解了Subjects
是如何运作的。 Subjects
是 hot Observables。他们没有坚持价值观,所以如果他们收到的onNext
没有订阅者,那么这个价值就会输给全世界。
您要查找的是BehaviorSubject
或ReplaySubject
,它们都会保留过去的值,并将这些值重新发送给新订阅者。在前一种情况下,您始终使用初始值
//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
封装。