Delay first 3 items by 1 second and the fourth by 4 seconds

Multi tool use
Delay first 3 items by 1 second and the fourth by 4 seconds
I'm trying to display the first 3 numbers each one delayed by 1 second and the fourth one by 4 seconds. Unfortunately, my code displays the four numbers by 1 second
import { from, of, race, timer, interval } from 'rxjs';
import { groupBy, mergeMap, toArray, map,merge, reduce, concatMap, delay, concat, timeout, catchError, take } from 'rxjs/operators';
const obs$ = from([1,2,3]).pipe(concatMap(a => of(a).pipe(delay(1000))));
const obs2$ = of(4).pipe(delay(4000));
const result$ = obs$.pipe(merge(obs2$));
const subscribe = result$.subscribe(val => console.log(val));
It displays
1234|
instead of
123----4|
this question is entirely for learning rxjs as beginner and has been tested on https://stackblitz.com
1 Answer
1
METHOD 1
The merge
operator subscribes to both observable (obs$
and obs2$
) at the same time. Therefore the result you get from your code may be explained as follows:
merge
obs$
obs2$
obs$ -----1-----2-----3
obs2$ -----------------------4
result$ -----1-----2-----3-----4
You may achieve your goal by forcing merge
to subscribe only one observable at a time by providing the second argument as 1 (which is Number.POSITIVE_INFINITY
by default) like the following:
merge
Number.POSITIVE_INFINITY
const obs$ = from([1,2,3]).pipe(concatMap(a => of(a).pipe(delay(1000))));
const obs2$ = of(4).pipe(delay(4000));
// Provide the concurrency (second) argument as 1
const result$ = obs$.pipe(merge(obs2$, 1));
const subscribe = result$.subscribe(val => console.log(val));
METHOD 2
Use concat
instead of merge
:
concat
merge
const obs$ = from([1, 2, 3]).pipe(concatMap(a => of(a).pipe(delay(1000))));
const obs2$ = of(4).pipe(delay(4000));
const result$ = concat(obs$, obs2$);
const subscribe = result$.subscribe(val => console.log(val));
METHOD 3
Otherwise you simply make use of the second parameter of concatMap
which is the index (starts from 0) of emitted items.
concatMap
const obs$ = from([1, 2, 3, 4]);
const delayed$ = obs$.pipe(
concatMap((value, index) => {
if (index <= 2) {
// Delay the first 3 items by 1 sec
return of(value).pipe(delay(1000));
} else {
// Delay other items (here the 4th item) by 4 sec
return of(value).pipe(delay(4000));
}
})
);
delayed$.subscribe(x => console.log(x));
See updated answer
– siva636
Jul 3 at 4:43
your answer totally rocks, really clear. Thanks man, you're great ! I didn't think merge would subscribe to both observable, but actually it's logical.
– John
Jul 3 at 21:29
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
could you explain me why my code doesn't work ?
– John
Jul 2 at 18:25