Reputation: 11389
Say I build an Observable
from an array like:
Rx.Observable.of(["a","b","c"])
or
Rx.Observable.from(["a","b","c"])
Then how can I emit those characters with an interval of 1s?
Upvotes: 2
Views: 1019
Reputation: 35491
Here's one approach.
You can map each array item into another observable that is delayed by 1000ms. This would give you an array of observables that are delayed by 1s.
[
Observable.from('a').delay(1000),
Observable.from('b').delay(1000),
Observable.from('c').delay(1000)
]
Since we have a 2D structure (array of observables), we need to flatten it to access the values for each observable in the array.
One of the flattening patterns we can use is concatAll. Because we're doing a map
followed by a concatAll
, there's a shorthand method - concatMap - that does this for us.
const { Observable } = Rx;
const wrapAndDelay = (val) => {
return Observable
.from(val)
.delay(1000);
};
const stream = Observable
.from([ "a", "b", "c" ])
.concatMap(wrapAndDelay);
stream.forEach(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.1/Rx.min.js"></script>
Another approach could be to use an interval to emit values each second. The interval
method by default emits a counter for each interval (0
, 1
, 2
, etc.) so we can map each of those values into an array entry at that index.
const { Observable } = Rx;
const arr = [ "a", "b", "c" ];
const stream = Observable
.interval(1000)
.timeInterval()
.take(arr.length) // say how many we need so we don't emit forever
.map(({ value }) => arr[value]);
stream.forEach(console.log);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.1/Rx.min.js"></script>
Upvotes: 1