【问题标题】:How to order stream merges?如何订购流合并?
【发布时间】:2017-10-14 16:11:10
【问题描述】:

我想合并两个相同来源的地图,以保证结果的顺序。这是我想通过的单元测试:

  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]

【问题讨论】:

  • 能发个jsbin吗?那样做实验会更容易。

标签: xstream-js


【解决方案1】:

我不是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+ 时发出 2 1, 3 在 t0+2。

【讨论】:

  • 感谢@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

【讨论】:

  • 谢谢!我认为源数组的重点是包含一些有用的数据。我用 1,2,3 初始化它以使示例简单,但我的实际情况涉及将数据记录映射到状态字符串,因此我无法将源数据替换为周期。
猜你喜欢
  • 2010-12-25
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 2018-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多