RxJS combineLatest:如何在一个值发生变化后发出?
RxJS combineLatest: how to get emit after just one value changes?
我正在尝试学习 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
以外的其他方法?
我在实际代码(比这个示例更大)中的问题是我需要在订阅后进行单独的初始化,这会在两个不同的地方剪切内容,而不是在前面清楚地设置初始值。
谢谢
我认为您误解了 Subjects
的工作原理。 Subjects
是 热门 Observable。他们不坚持价值观,所以如果他们收到一个没有订阅者的 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 次中有 9 次您会发现可能有一个 Observable
包装器。
我正在尝试学习 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
以外的其他方法?
我在实际代码(比这个示例更大)中的问题是我需要在订阅后进行单独的初始化,这会在两个不同的地方剪切内容,而不是在前面清楚地设置初始值。
谢谢
我认为您误解了 Subjects
的工作原理。 Subjects
是 热门 Observable。他们不坚持价值观,所以如果他们收到一个没有订阅者的 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 次中有 9 次您会发现可能有一个 Observable
包装器。