You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular单端点重复分页请求从Promise转为RxJS Observable实现

Angular Promise分页拉取全量数据转Observable实现方案

需求背景

Angular开发中需要将当前可运行的、基于Promise(async/await)实现的单接口分页拉取全量数据逻辑,改用Observables方案实现。
接口支持传入pageSize、page等分页和排序参数,不传参时返回接口最大允许条数(当前为1000条),数据总条数最高可达数万级,也可能仅存在少量数据。

API固定返回格式

{
  items: [...], // 对象数组
  totalNumberOfItems: 123 // 数据库中符合条件的总条目数
}

现有Promise实现(已省略try-catch和非必要逻辑)

async getAllItems(): Promise<any[]> {
  let page: number = 1;
  let pageSize: number;
  let items: any[] = [];
  let totalNumberOfItems: number;

  // 初始httpClient调用默认返回Observable
  let initialResponse = await this.someService.getItems().toPromise();
  items = [...items, ...initialResponse.items];
  pageSize = initialResponse.items.length;
  totalNumberOfItems = initialResponse.totalNumberOfItems;

  // 循环拉取直到拿完全量数据
  while (initialResponse.items.length < initialResponse.totalNumberOfItems) {
    page++;
    let nextResponse = await this.someService.getItems({ page, pageSize }).toPromise();
    items = [...items, ...nextResponse.items];
  }

  return items;
}

初始Observable实现思路框架

interface IResponse {
  items: any[];
  totalNumberOfItems: number;
}

getAllItems(): Observable<IResponse> {
  let page: number = 1;
  let pageSize: number;
  let totalNumberOfItems: number;

  return this.someService.getItems().pipe(
    tap(res => {
      pageSize = res.items.length;
      totalNumberOfItems = res.totalNumberOfItems;
    }),
    // 待实现:基于初始请求返回的参数迭代调用getItems,拼接所有返回结果
  );
}

已验证的可行实现方案(仍有优化空间)

getAllItems(): Observable<ItemsResponse> {
  let page: number = 1;
  let pageSize: number;
  let totalNumberOfItems: number;

  return this.service.getItems().pipe(
    tap(response => {
      pageSize = response.items.length;
      totalNumberOfItems = response.totalNumberOfItems;
    }),
    expand(response => {
      if (response.items.length < totalNumberOfItems) {
        const numRepeats = Math.ceil(totalNumberOfItems / pageSize);
        return (page < numRepeats) ? this.service.getItems({ page++, pageSize }) : EMPTY;
      } else {
        return EMPTY;
      }
    }),
    reduce((acc, response) => {
      acc.Items = [...acc.Items, ...response.Items];
      return acc;
    })
  );
}

内容的提问来源于stack exchange,提问作者ShockKhay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 07:15:03