保证发射之间间隔n秒,而无需首先等待

时间:2019-02-10 14:12:17

标签: rxjs

给出一个事件流,例如(每个-10ms

--A-B--C-D

有了debounceTime(20),我们得到了

-----------D

有了throttleTime(20),我们得到了

--A----C--

有了throttleTime(20, undefined, {leading: true, trailing: true},我们得到了

--A----CD

我该如何保证每次发射之间有足够的时间,例如使用20ms

--A-----C--D

通常,throttleTimetrailing: true最接近,但是有时可能导致trailing的输出与leading的输出过于接近。

可以在rxviz.com上找到示例代码

2 个答案:

答案 0 :(得分:2)

1。延误

为每个项目连接一个空的延迟,该延迟不发出任何东西,仅在给定的时间后完成。

const { EMTPY, of, concat } = Rx;
const { concatMap, delay } = RxOperators;

events.pipe(
  concatMap(item => concat(of(item), EMPTY.pipe(delay(20))))
);

enter image description here

2。间隔拉链

如果事件流发出项目的速度快于所需的延迟,则可以使用zip在间隔发出时发出事件。

const { interval, zip } = Rx;

zip(events, interval(20), (data, i) => data);

在任何情况下(例如,在任何情况下),此方法都不能保证每个发射的项目之间有n秒。当间隔大于期望的延迟,然后事件流中的间隔很小时。

例如,zip在您的示例中的发射延迟为20、30、50、60,最小延迟为20。
zip在20、30、65、70且最小延迟为20的情况下不能完美工作。

https://rxviz.com/v/2ORZLllO

答案 1 :(得分:0)

不确定是否可以使用现成的运算符来实现(可能有!),但是您可以通过在每个值上加时间戳并在两者之间添加必要的延迟来做到这一点:

  1. 为每个值添加时间戳
  2. 扫描序列并根据前一个值的有效时间戳计算相对延迟
  3. delay每个值按适当的数量
  4. concat生成的序列

下面是rxviz的说明。代码如下:

const minTimeBetween = 800

events.pipe(
  timestamp(),
  scan((a, x) => ({
    ...x,
    delayBy: a === null
      ? 0
      : Math.max(0, minTimeBetween - (x.timestamp - (a.timestamp + a.delayBy)))
  }), null),
  concatMap(x => of(x.value).pipe(
    delay(x.delayBy)
  ))
);