2017-10-14 97 views
1

我想合併兩個相同來源的地圖,以保證結果的順序。下面是我想一個單元測試通過:如何訂購流合併?

const source = xs.of(1,2,3) 
    const a = source.map(v=>v*10) 
    const b = source.map(v=>v*100) 
    const hist:number[] = [] 
    xs.merge(a,b).addListener({ 
    next: v=>hist.push(v), 
    }) 
    expect(hist).toEqual([10,100,20,200,30,300]) 

目前我得到的結果是這樣的:

Expected value to equal: 
    [10, 100, 20, 200, 30, 300] 
Received: 
    [10, 20, 30, 100, 200, 300] 
+0

可否請您發佈jsbin?然後,它會更容易實驗。 – user3743222

回答

2

我與xstream不是專家,所以我不建議你一個辦法。不過,我想我可以解釋爲什麼你會得到你所得到的輸出,因爲這是其他流媒體庫中的常見現象。

您有兩個來源的合併。 of運算符保證它將按順序發出數組值,運算符保證它將按照與接收值相同的順序發出轉換後的值等。但merge(a,b)不保證它將交織a和b的值。它確實保證它將按順序傳遞a的值,即保證b的順序,也就是說,它只保證結果輸出的部分順序。

給出一些要發射的值,哪些發射在什麼時間以及哪個順序與調度有關的問題。我不知道xstream在這個時間點暴露一個調度程序接口,從中您可以自定義值的排放調度。因此你被綁定到默認調度。

現在回到爲什麼你的順序觀察這些值:

  • 合併(A,B)第一,立即和同步連接到
    • 一個發出的所有值從數組
  • 合併(A,b),然後連接到b
    • b立即和發射順chronously從陣列

如果你想獲得1,2,3不同步發出的值,你需要使用其他運營商比of這樣做,或者明確地構建你的時間順序所有的值,即在t0時發射1,在t0 + 1時發射2,在t0 + 2時發射3。

+0

感謝@ user3743222的解釋。我在想圖書館可能有這個用例的解決方案,這似乎很普遍。 –

2

user3743222's answer獲取線索,使用periodic對列表進行排序。

更改:

//const source = xs.of(1,2,3) 
const source = xs.periodic(1).drop(1).take(3) 

...產生在控制檯:

10 100 20 200 30 300 

ESNextbin演示。

drop(1)是一種處理periodic開始於0的方法。你也可以在map函數中使用++v*10

+0

謝謝!我認爲源數組的重點是包含一些有用的數據。我用1,2,3進行了初始化,使示例變得簡單,但是我的實際情況涉及將數據記錄映射到狀態字符串,因此我無法用定期數據替換源數據。 –