Angular 11 : 并行获取所有页面

Angular 11 : Fetch all Pages in parallel

有一个外部 API,其中 returns 所有项目如下:

{
 page : 1,
 per_page : 10,
 total : 200,
 items : [],
}

我想获取所有页面。例如:在上面的场景中,总页数 = 20(Total/per_page 即 200/10)

进行第一次调用并了解页数然后并行进行其余所有调用并合并它的最佳方法是什么?

使用Angular 11 - concatMap、flatMap、forkJoin 等

解决方法:

根据@Michael 评论的更新代码如下所示:

getAllItems(): void {
    this.itemService.getItemsByPage(1).pipe(
        switchMap((itemPage: ItemPage) => {
          const totalPages = Math.ceil(itemPage.total/itemPage.per_page);
          const req$ = Array(totalPages).fill(1).map((_, index) =>
            this.itemService.getItemsByPage(index + 1)
          );
          return forkJoin(req$);
        })
      ).subscribe(
        res => {
          for (let page = 1; page <= res.length; page++) {
            //Collect all responses using res[page] 
          }
        },
        error => { 
          console.log("Error Fetching Items");
        }
      );
  }

您可以调用 API 来检索所有可用页面和项目总数,然后实现一些逻辑以使用 forkJoin 并行调用 API 您拥有的页面数

您还没有说明如何构造请求以在 HTTP 请求中输入总页数 20。所以我将使用伪 URL。

  1. 触发第一个请求。

  2. 使用switchMap切换到另一个请求,即获取 20 页。 Angular HTTP 请求在单次发射后完成。所以这里没有区别 b/n switchMapmergeMapconcatMapexhaustMap.

  3. 两种可能:

    3.1。如果每个页面都是一个单独的请求,则使用 forkJoin 并行获取它们。

    3.2。如果在单个请求中获取所有页面,则直接 return 它。

3.1: forkJoin

this.http.get('first request').pipe(
  switchMap((res: any) => {
    const totalPages = res['total'] / res['per_page'];
    // Convert the number 20 to 20 HTTP reqs. Again, not enough info is provided.
    const req$ = Array(totalPages).fill(1).map((_, index) =>
      this.http.get('page index+1')
    );
    return forkJoin(req$);
  })
).subscribe(
  res => {
    // res: ['res for page 1', 'res for page 2', ..., 'res for page 20'];
  },
  error => { }
);

3.2: 单个请求

this.http.get('first request').pipe(
  switchMap((res: any) => 
    this.http.get('url for 20 pages')
  )
).subscribe(
  res => {
    // res: depends on the backend;
  },
  error => { }
);