2014-09-02 61 views
2

在我的系統中,我有一個源代碼,兩個「步驟」將源映射到一個新值,然後結合這兩個步驟來創建最終值。通過該系統的初始運行工程,我希望,產生3如何同步RxJS更新以使中間值不通過流?

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

這就是combineLatest的工作方式,它確實令人困惑,因爲它允許您指出的這些暫時不一致的狀態。從combineLatest學習的關鍵是它發出一個新的項目,只要其中一個源發出一個新項目,並且它部分地完成,它沒有任何種類的「等待」機制。在圖中,http://rxmarbles.com/#combineLatest

您可能需要的是zip運算符。 Zip等待其輸入發出相互匹配的項目。換句話說,一旦來自所有輸入的所有第n項已經發射,則zip的輸出發出其第n項。它非常適用於您有source生成stepOnestepTwo並且您想要結合stepOnestepTwo的鑽石套件。

在圖中,http://rxmarbles.com/#zip

請記住zip假設輸入具有相同的發射頻率。在其他情況下,如果排放的頻率不同,您可能需要將stepOne中的項目與stepTwo組合在一起。那麼你需要使用combineLatest

+0

感謝您的回答,並鏈接到http://rxmarbles.com。這非常有用,而且很有趣! – 2014-09-03 18:21:09

+1

更多閱讀之後,我發現我可以使用Bacon.js和[無故障更新](https://github.com/baconjs/bacon.js/issues/272)特性後的行爲。我不認爲RxJS有支持,請有人糾正我,如果我錯了。 – 2014-09-04 16:42:43

+0

RxJS不會,但是這並不阻止你完成你需要的任何事情。它將以不同的方式。 Zip是大多數情況下的解決方案。 Bacon.js的內存使用量也很大。 – 2014-09-04 18:10:08