rxjs - 2 API calls (shallow call vs deep call)

Viewed 152

I have 2 calls. First call and second call.

Second call takes longer 99% of the time and once it's complete has all the info I need. But I call first call which is quick and limited info to appease user.

If Second call finishes before first - cancel first call.

How do i achieve this?

let myResult$ = someOperator([
myApiService.call1(),
myApiService.call2()]).pipe(
    //do something after each call completes (twice in Total)
);
2 Answers

As Oles Savluk correctly points out:

let myResult$ = merge([
    myApiService.call1(),
    myApiService.call2()
]);

Note that it results in two single, separate values in the observable. If you need the result of both requests in one value array, use forkJoin. Do not forget to subscribe / unsubscribe to myResult$.

EDIT: Untested, but if you want to give superiority to one of the observables:

let superior$ = myApiService.call1();
let inferior$ = myApiService.call2();
let myResult$ = merge([superior$, inferior$]).pipe(
    takeUntil(superior$)    
);

The merge makes sure both observables get their shot, and he takeUntil makes sure that if the superior comes first, the result will finish immediately.

Option 1.
I like @Wouter van Koppen's asnwer, yet few changes would make it great:

const long$ = myApiService.longOperation().pipe(share()) 
const short$ = myApiService.shortOperation$.pipe(takeUntil(long$))

merge(long$, short$).subscribe(console.log);

share is used so that takeUntil(long$) and merge(long$ would share the same subscription thus preventing longOperation from getting subscribed twice.

Option 2.

shortOperation$
.pipe(
  takeUntil(
    longOperation$.pipe(
      tap(x => {
       // run some code
      })
    )
  )
)
.subscribe(console.log);
Related