Search code examples
eventsrxjsrxjs5timed

RxJs: How to emit events at predefined times?


I have some pre-defined events set to occur at specific times. And I have a timer, like this:

const timer = Rx.Observable.interval(100).timeInterval()
    .map(x => x.interval)
    .scan((ms, total) => total + ms, 0)

The timer emits something close to 100,200,300,400,500 (although in reality it's more like 101,200,302,401,500...which is totally fine) I also have some stuff I want to do at certain times. For example, let's say I want to do stuff at the following times:

const stuff = Rx.Observable.from([1000, 2000, 2250, 3000, 5000]);

What I'd like is to combine "stuff" and "timer" in such a way that the resulting stream emits a value once per time defined in "stuff" at that time (or ever so slightly later). in this case, that would be t=1000 ms, 2000 ms, 2250 ms, 3000 ms and 5000 ms. Note: the 2250 guy should emit around time 2300 because of the interval size. that's fine. they just can't come early or more than once.

I have one solution, but it's not very good. it re-starts "stuff" every single step (every single 100 ms in this case) and filters it and takes 1. I would prefer that, once an event is emitted from "stuff", that it be gone, so subsequent filters on it don't have those values.

In the real application, there will be stuff and stuff2 and maybe stuff3...(but I will call them something else!)

Thanks in advance! I hope that was clear.


Solution

  • If I've understood what you're after correctly, this should be achievable with a simple projection:

    const times$ = stuff.flatMap(x => Rx.Observable.timer(x));
    

    Here's a working sample: https://jsbin.com/negiyizibu/edit?html,js,console,output

    Edit

    For the second requirement, try something like this:

    const times$ = Rx.Observable
                     .from([{"val":"jeff", "t": 1000}, {"val":"fred", "t": 2500}])
                     .flatMap(x => Rx.Observable.timer(x.t).map(y => x.val));
    

    https://jsbin.com/cegijudoci/edit?js,console,output