【问题标题】:How to repeat same network request multiple times with different parameters in rxjs (Angular)?如何在rxjs(Angular)中使用不同的参数多次重复相同的网络请求?
【发布时间】:2020-06-16 02:15:40
【问题描述】:

下面有一个 mat-table 元素和一个 mat-paginator 元素。 该表填充了来自 API 的数据。 我的 API 默认按请求返回 10 个元素,但我需要在表格中显示 25 个元素,因此我需要发出 3 个 API 请求来填充 mat-table。

如何使用不同的参数重复调用 API,然后将所有三个响应合并为一个 observable?

就我而言 - 我想用不同的 pageNumber 重复 getPlanetsPage(pageNumber),所以这是棘手的部分(我试图通过 repeat() 解决这个问题...):

return this.planetService.getPlanetsPage(dontKnowHowToDoItArg)
  .pipe(
    repeat(Math.ceil(this.paginator.pageSize / this.countOfPlanetsPerPage))
  );

来自 ngAfterViewInit() 的完整代码:

this.paginator.page
  .pipe(
    startWith({}),
    switchMap((paginatorData) => {
      this.isLoadingResults = true;

      const indexOfFirstElementToRenderInTable = this.paginator.pageSize * this.paginator.pageIndex;
      if (this.planets[indexOfFirstElementToRenderInTable]) {

        this.planetsToRender = this.planets.slice(indexOfFirstElementToRenderInTable, this.paginator.pageSize * (this.paginator.pageIndex + 1));
        return EMPTY;
      } else {
        return this.planetService.getPlanetsPage(dontKnowHowToDoItArg)
          .pipe(
            repeat(Math.ceil(this.paginator.pageSize / this.countOfPlanetsPerPage))
          );
      }
    }),
    map(planetsPage => {
      this.isLoadingResults = false;
      this.isRateLimitReached = false;
      this.resultsLength = planetsPage.count;
      return planetsPage.results;
    }),
    catchError(() => {
      this.isLoadingResults = false;
      this.isRateLimitReached = true;
      return of([]);
    })
  ).subscribe((planetsArr: Planet[]) => {
    this.planets.push(...planetsArr);
    const indexOfFirstElementToRenderInTable = this.paginator.pageSize * this.paginator.pageIndex;

    this.planetsToRender = this.planets.slice(indexOfFirstElementToRenderInTable, this.paginator.pageSize * (this.paginator.pageIndex + 1));
    this.requestNo++;
  });

http服务获取方法:

getPlanetsPage(pageNumber): Observable<any> {
  return this.httpClient.get(this.planetsBasicPageUrl, {
    params: new HttpParams()
      .set('page', pageNumber.toString())
  });
}

【问题讨论】:

  • 你能在你的 API 中指定元素数量而不使用默认行为(10 个元素)吗?或者,您可以更改表中的默认元素数量以适应 API 的默认行为(10 个元素)吗?因此,您可以避免困难的处理。
  • @Yeheshuah 我正在使用swapi.dev。我需要得到行星。据我所知,我无法指定 API 响应的元素数量。我认为这个问题stackoverflow.com/questions/57269110/… 与我的问题相似,也许这种方法(使用do-while)是正确的,但是如何使用rxjs 获得这种行为?
  • 你能创建一个 StackBlitz 演示吗?
  • 我猜,我的问题的答案是使用 expand -> ncjamieson.com/understanding-expand

标签: angular http rxjs observable mat-table


【解决方案1】:

有一个专门用于递归调用的 rxjs 运算符,请查看EXPAND。以下是适合您的方法

import { from, EMPTY } from 'rxjs';
import { expand, tap, switchMap } from 'rxjs/operators';
...



let results = [] // to concatenate your data each time
let pageNumber = 1; // to count your calls, you need 3 calls so it will be your stop condition



getPlanetsPage(pageNumber): Observable<any> {
 return this.httpClient.get(this.planetsBasicPageUrl, {
   params: new HttpParams()
  .set('page', pageNumber.toString())
 });
}


getPlanetsPage(1).pipe(
  tap(res => {
       this.pageNumber++; 
       results = results.concat(res)  // on success add new results to our array
     }),
  expand((_) => this.pageNumber <=3 
         ? getPlanetsPage(this.pageNumber)
         : EMPTY;
  )
).subscribe(console.log)

简洁明了,你可以查看我在 dev.to 上关于递归调用的帖子https://dev.to/fatehmohamed14/recursive-http-calls-the-rxjs-way-d61

【讨论】:

    【解决方案2】:

    希望this 有所帮助。

    // demonstrate combining 3 API requests into 1
    loadPage(i: number) {
      this.result$ = combineLatest(
        [i * 3, i * 3 + 1, i * 3 + 2].map((i) => this.getAPI(i))
      ).pipe(map(([a, b, c]) => [...a, ...b, ...c]));
    }
    
    // simulate an API request
    getAPI(page = 0) {
      let pageResult = [];
      for (let i = page * 10; i < (page + 1) * 10; i++) {
        pageResult.push({
          row: i,
          text: (Math.random() * Number.MAX_SAFE_INTEGER).toString(36),
        });
      }
      return of(pageResult)
        .pipe(delay(Math.random() * 200 + 200)); // simulate variant response times
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-09
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      • 2021-06-14
      • 1970-01-01
      • 2018-01-07
      • 2019-01-20
      相关资源
      最近更新 更多