【问题标题】:Angular 11 : Fetch all Pages in parallelAngular 11:并行获取所有页面
【发布时间】:2021-06-10 05:22:45
【问题描述】:

有一个外部 API 可以返回以下所有项目:

{
 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");
        }
      );
  }

【问题讨论】:

  • 您知道要获取的 20 个页面的 url/资源吗?模式是什么?

标签: angular parallel-processing


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您尚未展示如何构造请求以在 HTTP 请求中输入总页数 20。所以我将使用伪 URL。

    1. 触发第一个请求。

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

    3. 两种可能:

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

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

    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 => { }
    );
    

    【讨论】:

    • 在“Array.fill”上出现错误。此外,添加了如上所示的代码 sn-p。 API 已分页。
    • 应该是Array(totalPages).fill(1),抱歉。请再试一次。 1 可以是任何值,这并不重要,因为我们已经使用 map 函数的 index 参数映射到 HTTP 请求。
    • 我们需要提及 take(1) 还是需要显式关闭 observable?
    • Angular HTTP observables 默认为take(1)forkJoin 在外部是具有单个发射的单个可观察对象。所以它不是必需的。
    • 谢谢!!按预期工作。
    猜你喜欢
    • 2020-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 2019-08-21
    • 2016-07-26
    • 2021-12-26
    相关资源
    最近更新 更多