How to get notification when the last observable finish emitting values?

Ric*_*d77 0 rxjs angular

We used to have one call to the API

reqFinanceDataWithFilters(req): Observable<any> {
  return this.http.post(env.baseUrl + req.url, req.filters)
    .pipe(map(this.extractResults));
}
Run Code Online (Sandbox Code Playgroud)

The above request would return a giant json that takes time to build at the API level. So we decided to break it into 4 calls. Now we have:

reqViz.url = 'viz-data';
this.reqFinanceDataWithFilters(reqViz)
    .pipe(...)

reqTableTop.url = 'summary-data';
this.reqFinanceDataWithFilters(reqTableTop)
    .pipe(...)

reqTableMiddle.url = 'monthly-expenses';
this.reqFinanceDataWithFilters(reqTableMiddle)
    .pipe(...)
Run Code Online (Sandbox Code Playgroud)

So I have 4 independant calls to the API. The order the response for each of them is not important. All I want to know when the last one is done receiving response so that I can hide the spinner and display the page.

Thanks for helping

小智 5

forkJoin(/* your observalbes here */).subscribe(values => {
   // do stuff, all observables have completed
})
Run Code Online (Sandbox Code Playgroud)

https://www.learnrxjs.io/operators/combination/forkjoin.html


Sid*_*era 5

您可以forkJoin为此使用。

LearnRxJS.io

为什么要使用forkJoin?

当您有一组可观测对象且仅在乎每个对象的最终发射值时,最好使用此运算符。一个常见的用例是,如果您希望在页面加载(或其他事件)时发出多个请求,并且只希望在收到所有人的响应后才采取措施。这样,它类似于您可能使用Promise.all的方式。

请注意,如果提供给forkJoin错误的任何内部可观察变量将丢失任何其他内部可观察变量的值,如果您没有正确地捕获内部可观察变量的错误,则该变量将已经或已经完成。如果您只关心所有内部观测值是否成功完成,则可以从外部捕获错误。

在这里,尝试一下:

import { forkJoin } from 'rxjs';
import { delay, catchError } from 'rxjs/operators';

...

loading = true;
reqViz.url = 'viz-data';
const viz = this.reqFinanceDataWithFilters(reqViz)
  .pipe(
    ...
    catchError(error => of(error))
  )

reqTableTop.url = 'summary-data';
const summary = this.reqFinanceDataWithFilters(reqTableTop)
  .pipe(
    ...
    catchError(error => of(error))
  )

reqTableMiddle.url = 'monthly-expenses';
const monthy = this.reqFinanceDataWithFilters(reqTableMiddle)
  .pipe(
    ...
    catchError(error => of(error))
  )

forkJoin(viz, summary, monthly)
  .subscribe(
    res => {
      loading = false;
    }
  )
Run Code Online (Sandbox Code Playgroud)