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

Multi tool use
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));





could you explain me why my code doesn't work ?
– John
Jul 2 at 18:25





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.

IKYkgfCXswQEBai,fPcukj
a,cma9 NTx2d

Popular posts from this blog

Rothschild family

Cinema of Italy