We used to have one call to the API
reqFinanceDataWithFilters(req): Observable{ return this.http.post(env.baseUrl + req.url, req.filters) .pipe(map(this.extractResults)); }
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(...)
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
forkJoin(/* your observalbes here */).subscribe(values => { // do stuff, all observables have completed })
https://www.learnrxjs.io/operators/combination/forkjoin.html
您可以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; } )