Kuan
Kuan

Reputation: 11389

How to build an Observable from an array and emit items with an interval of 1s?

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

Answers (1)

nem035
nem035

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

Related Questions