问题描述
给定一个事件流,例如(每个 -
是 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
通常带有 trailing: true
的 throttleTime
最接近,但有时会导致 trailing
输出太接近领先
输出.
示例代码可以在
2.ConcatMap 到计时器
将每个项目映射到从给定项目开始并在给定时间后完成的计时器.当计时器完成时,将发出下一项.计时器本身发出的值将被忽略.
const { timer } = Rx;const { concatMap, ignoreElements, startWith } = RxOperators;事件$.pipe(concatMap(item => timer(20).pipe(ignoreElements(), startWith(item))));
3.有间隔的压缩(不是最佳的)
如果您的事件流发出项目的速度比所需的延迟快,您可以使用 zip
在间隔发出时发出事件.
const { interval, zip } = Rx;const { 地图 } = RxOperators;zip(event$, interval(20)).pipe(map(([item, i]) => item));
此方法不能保证在所有情况下每个发出的项目之间 n
秒,例如当间隔大于所需延迟时,事件流中紧跟着一个小间隔.
例如 zip
在您的示例中工作,在 20、30、50、60 发出,最小延迟 20.zip
在 20, 30, 65, 70 和最小延迟 20 的发射时无法完美工作.
当 interval
发出的速度比事件进入的速度快时,这些间隔项只会堆积在 zip
中.如果是这种情况,zip
将立即从其堆栈中压缩任何具有已经存在的间隔项的新事件,从而在没有预期延迟的情况下发出事件.
Given an event stream like (each -
is 10ms
)
--A-B--C-D
With debounceTime(20)
we get
-----------D
With throttleTime(20)
we get
--A----C--
With throttleTime(20, undefined, {leading: true, trailing: true}
we get
--A----CD
How can I instead guarantee that I have that much time between each emit, so for example with 20ms
--A-----C--D
In general the throttleTime
with the trailing: true
gets closest, but it can sometimes cause the trailing
output to be too close to the leading
output.
Sample code can be found on rxviz.com
1. Concat a delay
Concatenate an empty delay to each item, that doesn't emit anything and only completes after a given time.
const { EMTPY, of, concat } = Rx;
const { concatMap, delay } = RxOperators;
event$.pipe(
concatMap(item => concat(of(item), EMPTY.pipe(delay(20))))
);
2. ConcatMap to a timer
Map every item to a timer that starts with the given item and completes after a given amount of time. The next item will be emitted when the timer completes. Values emitted by the timer itself are ignored.
const { timer } = Rx;
const { concatMap, ignoreElements, startWith } = RxOperators;
event$.pipe(
concatMap(item => timer(20).pipe(ignoreElements(), startWith(item)))
);
3. Zip with an interval (not optimal)
If your event stream emits items faster than the desired delay you could use zip
to emit events when an interval emits.
const { interval, zip } = Rx;
const { map } = RxOperators;
zip(event$, interval(20)).pipe(map(([item, i]) => item));
This method won't guarantee n
seconds between every emitted item in all circumstances, e.g. when there is a gap larger than the desired delay followed by a small gap in the event stream.
E.g zip
works in your example with emits at 20, 30, 50, 60 with min delay 20.zip
won't work perfectly with emits at 20, 30, 65, 70 with min delay 20.
When the interval
emits faster than events are coming in, those interval items will just pile up inside zip
. If this is the case zip
will immediately zip any new event with an already present interval item from its stack causing events to be emitted without the intended delay.
这篇关于保证发射之间的 n 秒,而不用最初等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!