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]
4

2 回答 2

2

我不是专家xstream,所以我无法向您提出解决方案。但是,我想我可以解释为什么你会得到你得到的输出,因为这在其他流媒体库中很常见。

您有两个来源的合并。of运算符保证它将按顺序发出数组值,运算map符保证它将按与接收值相同的顺序发出转换后的值,等等。但merge(a,b)不保证它将交错 a 和 b 的值。它确实保证它将按顺序传递 a 的值,按顺序传递 b 的值,即它只保证结果输出的部分顺序。

给定一些要发出的值、在什么时间发出哪些以及以何种顺序发出的问题与调度有关。目前我不知道xstream公开调度程序接口,您可以从中自定义值的发送调度。因此,您必须使用默认调度。

现在回到为什么按顺序观察这些值:

  • merge(a,b) 首先连接到 a
    • a 立即同步地发出数组中的所有值
  • merge(a,b) 然后连接到 b
    • b 立即同步地发出数组中的所有值

如果您想获得不同步发出的值 1、2、3,则需要使用另一个运算符而不是of这样做,或者显式构造定时序列,即在 t0 时发出 1,在 t0+1 时发出 2,在 t0+ 时发出 3 2.

于 2017-10-14T17:10:54.767 回答
2

user3743222 的答案中获取线索,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。也可以++v*10map功能中使用。

于 2017-10-14T17:46:28.743 回答