2017-10-14 68 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进行了初始化,使示例变得简单,但是我的实际情况涉及将数据记录映射到状态字符串,因此我无法用定期数据替换源数据。 –