RxJS5 emit array items over time and repeat forever

1.4k views Asked by At

I want to emit array items over time (a one second interval between each emit) and when all items have been emitted, repeat over and over.

I know how to do this, but I want to know if there is something more succinct than ..

const MY_ARRAY = ['one','two','three'];
const item$ = Rx.Observable.interval(1000).take(MY_ARRAY.length).repeat().map(x => MY_ARRAY[x]);
item$.subscribe(x => console.log(x));

thanks

output is ..

"one"

"two"

"three"

"one"

"two"

"three"

etc

EDIT:

ATOW, the answers here are summarised as ..

const ARR = ['one', 'two', 'three'];

// TAKE YOUR PICK THEY ALL DO THE SAME
const item$ = Rx.Observable.interval(1000).map(i => ARR[i % ARR.length]);
// const item$ = Rx.Observable.interval(1000).zip(ARR, (a, x) => x).repeat();
// const item$ = Rx.Observable.interval(1000).zip(ARR).repeat().map(x => x[1]);
// const item$ = Rx.Observable.interval(1000).take(ARR.length).repeat().map(i => ARR[i]);

item$.subscribe((x) => {
  console.log(x);
});
4

There are 4 answers

6
Meir On BEST ANSWER
Observable.interval(1000).map(i => MY_ARRAY[i % MY_ARRAY.length])
1
Bazinga On

You can use the zip operator:

const interval$ = Rx.Observable.interval(1000);
const items$ = Rx.Observable.from([1,2,3]);

const itemsOverTime$ = interval$.zip(items$).repeat();


itemsOverTime$.subscribe(([time, val]) => {
  console.log(val);
  // 1
  // 2
  // 3
  // 1
  // 2
  // 3
});
1
Asti On

zip is the go-to operator here, but using Observable.from dumps all values on subscribe, and requires zip to keep a copy of the values. This isn't ideal for large arrays. The original IEnumerable<T> overload for zip is implemented as zipIterable.

const MY_ARRAY = ['one','two','three'];
Rx.Observable.interval(1000).zipIterable(MY_ARRAY, (_, v) => v).subscribe(v => console.log(v))
1
T. Thuan On

use zip to combine stream from interval and from so that for each interval time, an value will be emitted. Then you pipe the above observable with repeat operator with no parameter to emit value forever.

const { interval, from, zip } = require('rxjs');
const { repeat } = require('rxjs/operators')

const itemsOverTime$ = zip(
    interval(1000),
    from(MY_ARRAY)
).pipe(repeat());

itemsOverTime$.subscribe(([time, val]) => {
    console.log(val);
});