简体   繁体   中英

Handle multiple http requests and wait for all to complete using Angular RxJs Observables

I am using Observables, I have a use case where:

  1. I have to get "pages" from service which gives me Page[]
  2. For each of those "pages" I have to get the "sections" from other service
  3. Also on subscribe of all those "sections" I have to do some action based on the data returned.

The concern is once all of those requests are completed then have to do some action.

you need use mergeMap and forkJoin

When using forkJoin you can fire parallel request at the same time and it will wait till all requests are completed.

this.http.get('/api/pages/')
    .map((res: any) => res.json())
    .mergeMap((pages: any[]) => {
      if (pages.length > 0) {
        return Observable.forkJoin(
          pages.map((page: any) => {
            return this.http.get('/api/sections/' + page_id)
              .map((res: any) => {
                let section: any = res.json();
                // do your operation and return
                return section;
              });
          });
        );
      }
      return Observable.of([]);
    });
}

In general when nesting async calls try to stay as flat as possible. Otherwise, you're creating callback hell which make things even more complicated than just with regular iterative code:

this.http.get('/api/pages/')
  .map((res: Response) => res.json())
  .concatMap((pages: Page[]) => {
    const observables = pages.map(p => this.http.get('whatever' + p.id));

    return Observable.forkJoin(observables, (...results) => 
      results.map((result, i) => {
        pages[i].sections = result;
        return pages[i];
      })
    )
  })
  .subscribe(pagesWithSections => ...);

The forkJoin() operator takes as argument a selector function that lets you work with the results of all the source Observables. I'm using it to update the original pages array and return it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM