Reputation: 19202
I have a keyboard event that causes an animation to play. It's possible for the user to produce more events than the rate that the animation plays so I want to create a queue that will eventually empty firing one by one after a certain amount of delay.
Desired marble diagram:
=================================================
user: START|a-b-c-----------------------------
result: START|-350ms--a--350ms--b--350ms--c-----
=================================================
The user
fires 3 events rapidly (a
b
c
). After event a
fires, 350ms timer starts. After that timer is finishes, the result
fires a
and starts another 350ms timer. After that timer is done it fires b
. Basically, if a timer is in progress, I want to add it to the queue and emit it later. The rate cannot exceed 350ms and I want every event.
I want to throttle the output of the events to 350ms but I don't want to use the throttle
operator because I don't want to loose any events (I want a
, b
, and c
to fire).
A Javascript RxJS solution is preferred but I'll accept any answer with Rx operators in any language.
Upvotes: 1
Views: 163
Reputation: 9880
This seems to do the trick:
import { fromEvent, concat, timer } from 'rxjs';
import { tap, concatMap, filter } from 'rxjs/operators';
fromEvent(document, 'keypress')
.pipe(
filter((e: KeyboardEvent) => e.code === 'Space'),
concatMap(() => timer(350))
).subscribe(console.log)
Edit: The concat()
operator is redundant. Removed.
Upvotes: 2