【问题标题】:RxJS combineLatest: how to get emit after just one value changes?RxJS combineLatest:如何在一个值更改后发出?
【发布时间】:2015-09-27 20:45:45
【问题描述】:

我正在尝试学习 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以外的其他方法?

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

谢谢

【问题讨论】:

    标签: reactive-programming rxjs


    【解决方案1】:

    我认为您误解了Subjects 的工作原理。 Subjects 热门的 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 次中有 9 次您会发现它可能有一个 Observable 包装器。

    【讨论】:

    • @akauppi 是的,鼠标拖动当然是可观察的事件,请查看 fromEvent。当您拥有更多的 Rx 经验时,您可以学习如何将所有这些从可观察鼠标事件的源头一直到仅使用 Rx 运算符的最终可观察结果串在一起,而无需直接使用 @987654332 @.
    猜你喜欢
    • 1970-01-01
    • 2019-05-05
    • 2021-05-09
    • 2017-06-25
    • 1970-01-01
    • 2019-04-01
    • 2021-10-29
    • 2018-04-18
    • 1970-01-01
    相关资源
    最近更新 更多