Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Separate observable values by specific amount of time in RxJS

What would be the most idiomatic way to yield values of an Observable by a specific amount of time? For example, let's say I have an Observable created from a big Array and I want to yield a value every 2 seconds. Is a combination of interval and selectMany the best way?

like image 665
Sergi Mansilla Avatar asked Feb 09 '14 16:02

Sergi Mansilla


People also ask

What is Observable interval?

interval returns an Observable that emits an infinite sequence of ascending integers, with a constant interval of time of your choosing between those emissions. The first emission is not sent immediately, but only after the first period has passed.

What is timer in RxJS?

RxJS timer() operator is a creation operator used to create an observable that starts emitting the values after the timeout, and the value will keep increasing after each call.

What is concatMap in RxJS?

concatMap operator is basically a combination of two operators - concat and map. The map part lets you map a value from a source observable to an observable stream. Those streams are often referred to as inner streams.


2 Answers

For your specific example, the idea is to map each value from the array to an observable that will yield its result after a delay, then concatenate the resulting stream of observables:

var delayedStream = Rx.Observable     .fromArray([1, 2, 3, 4, 5])     .map(function (value) { return Rx.Observable.return(value).delay(2000); })     .concatAll(); 

Other examples might indeed make use of timer or interval. It just depends.

For example, if your array is really really big, then the above will cause a fair amount of memory pressure (because it is creating N observables for a really large N). Here is an alternative that uses interval to lazily walk the array:

var delayedStream = Rx.Observable     .interval(2000)     .take(reallyBigArray.length) // end the observable after it pulses N times     .map(function (i) { return reallyBigArray[i]; }); 

This one will yield the next value from the array every 2 seconds until it has iterated over the entire array.

like image 192
Brandon Avatar answered Oct 09 '22 03:10

Brandon


I think that using zip produce better and more readable code, still using just 3 observables.

var items = ['A', 'B', 'C'];  Rx.Observable.zip(   Rx.Observable.fromArray(items),   Rx.Observable.timer(2000, 2000),     function(item, i) { return item;} ) 
like image 30
farincz Avatar answered Oct 09 '22 04:10

farincz