如何同步RxJS更新,以便不通过流传递中间值?

时间:2014-09-02 22:15:42

标签: rxjs reactive-extensions-js

在我的系统中,我有一个源,两个"步骤"将源映射到新值,然后将这两个步骤组合在一起以创建最终值。该系统的初始运行正如我所希望的那样,产生一个3的总和。

var source = new Rx.BehaviorSubject(0);    
var stepOne = source.map(function (value) {
    return value + 1;
});
var stepTwo = source.map(function (value) {
    return value + 2;
});    
var sum = Rx.Observable.combineLatest(
    stepOne,
    stepTwo,
    function (s1, s2) {
        console.log('calc sum: ' + (s1 + s2));
        return s1 + s2;
    }).subscribe(function (sum) {
    });

输出:

> calc sum: 3

但如果我为源代码输入一个新值,我会得到两个结果:

source.onNext(1);

> calc sum: 4
> calc sum: 5

第一个是中间结果......当新的源值通过系统的一部分时,然后在所有值完成传播时得到最终结果。

所以我的问题是,推荐的配置方式是什么,以便推送到源中的新值将以原子方式通过系统并仅生成一个总和结果?

谢谢!

1 个答案:

答案 0 :(得分:1)

combineLatest如何工作,确实令人困惑,因为它允许这些暂时不一致的状态如你所指出的那样。从combineLatest学习的关键是,每当任何其中一个来源发出新项目时,它会发出一个新项目,并且它会部分地发布,它没有任何内容等待"等待"机构。

在图表中,http://rxmarbles.com/#combineLatest

您可能想要的是zip运算符。 Zip等待其输入以发出彼此匹配的项目。换句话说,一旦所有输入中的所有第n个项目都被发出,zip的输出就会发出它的第n个项目。这个钻石案例非常适合您source生成stepOnestepTwo,并希望合并stepOnestepTwo

在图表中,http://rxmarbles.com/#zip

请记住zip假设输入的排放频率相同。在其他情况下,当它们具有不同的排放频率时,您可能希望将stepOne中的项目与stepTwo组合。然后,您需要使用combineLatest