danday74
danday74

Reputation: 57036

RxJS5 emit array items over time and repeat forever

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);
});

Upvotes: 3

Views: 1480

Answers (4)

T. Thuan
T. Thuan

Reputation: 1

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);
});

Upvotes: 0

Asti
Asti

Reputation: 12677

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))

Upvotes: 1

Meir
Meir

Reputation: 14385

Observable.interval(1000).map(i => MY_ARRAY[i % MY_ARRAY.length])

Upvotes: 6

Bazinga
Bazinga

Reputation: 11224

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
});

Upvotes: 5

Related Questions