zip的替代方法,只要任何observable发出一个值,就会产生值

时间:2016-03-09 17:02:26

标签: rxjs

目前,zip只会在所有压缩的observable产生值时生成一个值。例如。来自文档:

  

将指定的可观察序列或Promise合并为一个   通过使用选择器函数的所有的可观察序列   可观察序列产生了一个元素

我正在寻找一个可以观察到一个可观察的拉链的观察者,但会生成一个拉链可观察序列的数组,其中如果所有都生成一个值都没关系。

e.g。让我说我有勾选$,observ1,observ2 .. tick $总是每隔x秒生成一个值..而observ1和observ2只是不时产生.. 我期待我的流看起来像

[tick, undefined, observ2Res],
[tick, undefined, undefined],
[tick, observ1Res, observ2Res]
...
...

它不是最新组合,因为最新组合采用了给定观察值的最新值。

1 个答案:

答案 0 :(得分:2)

我相信buffer(或许sample)可能会让您走上正轨。 buffer方法接受一个用于定义缓冲区边界的Observable。生成的流会发出在该窗口中发出的任何项目(例如从buffer的RXJS文档中窃取的示例):

var source = Rx.Observable.timer(0, 50)
  .buffer(function () { return Rx.Observable.timer(125); })
  .take(3);

var subscription = source.subscribe(x => console.log('Next: ', x));

// => Next: 0,1,2
// => Next: 3,4,5
// => Next: 6,7

因此,我们现在可以在特定时间窗口内获取所有流的事件。在您的情况下,我们可以使用tick$来描述我们的采样周期,observ1observ2是我们想要缓冲的基础流:

const buffered1 = observ1.buffer(tick$);
const buffered2 = observ2.buffer(tick$);

这些流中的每一个将在每个tick $ period发出一次,并将从底层流中发出所有发出项的列表(在此期间)。 buffered流将发出如下数据:

|--[]--[]--[1, 2, 3]--[]-->

要获得所需的输出,我们可以选择仅查看每个缓冲结果的最新发射项,如果没有发出数据,我们可以传递null:

const buffered1 = observ1.buffer($tick).map(latest);
const buffered2 = observ2.buffer($tick).map(latest);

function latest(x) {
    return x.length === 0 ? null : x[x.length - 1];
}

我说明的上一个示例流现在看起来像这样:

|--null--null--3--null-->

最后,我们可以zip这两个流来获取最新的"在tick$间隔期间发出数据:

const sampled$ = buffered1.zip(buffered2);

sampled$流将通过observ1窗口从observ2tick$流中发出最新数据。这是一个示例结果:

|--[null, null]--[null, 1]--[1, 2]-->