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

如何使用Angular RxJS按顺序请求并将响应分配到对应列表?

按顺序发起HTTP请求并将响应分配到对应列表的解决方案

你需要按固定顺序发起多个HTTP请求,每个请求的响应要渲染到独立的HTML列表中,但当前使用concatMap只能逐个获取响应对象,无法区分每个响应对应的目标列表。以下是两种可行的解决方案:

方法一:为请求绑定目标标识

给每个请求包装一个包含目标列表标识的对象,在获取响应时直接根据标识赋值到对应列表:

步骤1:修改请求数组,添加目标标识

const reqWithTargets = [
  { 
    request: this.domainService.getDomain(filterNG).pipe(
      map(resp => resp.data), 
      finalize(() => this.loadingNG = false)
    ), 
    target: 'listNG' 
  },
  { 
    request: this.domainService.getDomain(filterCodAML).pipe(
      map(resp => resp.data), 
      finalize(() => this.loadingCodAML = false)
    ), 
    target: 'listCodAML' 
  },
  { 
    request: this.domainService.getDomain(filterTipoRating).pipe(
      map(resp => {
        resp.data.unshift({code: this.TIPO_RATING_ALL, description: this.translate.instant('tutti')});
        return resp.data;
      }), 
      finalize(() => this.loadingTipiRating = false)
    ), 
    target: 'listTipoRating' 
  },
  { 
    request: this.komodoService.listProvince$().pipe(
      finalize(() => this.loadingProvince = false)
    ), 
    target: 'listProvince' 
  },
  { 
    request: this.domainService.getDomain(filterGRA).pipe(
      map(resp => resp.data), 
      finalize(() => this.loadingGRA = false)
    ), 
    target: 'listGRA' 
  },
  { 
    request: this.anagraficaService.getListaFiliali({filter: {all: false}}).pipe(
      map(resp => resp.data), 
      finalize(() => this.loadingFiliali = false)
    ), 
    target: 'listFiliali' 
  }
];

步骤2:订阅时根据标识分配响应

from(reqWithTargets).pipe(
  concatMap(item => item.request.pipe(
    map(resp => ({ data: resp, target: item.target }))
  ))
).subscribe(({ data, target }) => {
  switch(target) {
    case 'listNG':
      this.listNG = data;
      break;
    case 'listCodAML':
      this.listCodAML = data;
      break;
    case 'listTipoRating':
      this.listTipoRating = data;
      break;
    case 'listProvince':
      this.listProvince = data;
      break;
    case 'listGRA':
      this.listGRA = data;
      break;
    case 'listFiliali':
      this.listFiliali = data;
      break;
  }
});

步骤3:HTML中渲染对应列表

<!-- NG列表 -->
<div *ngIf="listNG.length">
  <h3>NG 列表</h3>
  <ul>
    <li *ngFor="let item of listNG">{{ item.description }}</li>
  </ul>
</div>

<!-- CodAML列表 -->
<div *ngIf="listCodAML.length">
  <h3>CodAML 列表</h3>
  <ul>
    <li *ngFor="let item of listCodAML">{{ item.description }}</li>
  </ul>
</div>

<!-- 其他列表依此类推 -->

方法二:利用请求数组索引匹配列表

由于请求数组的顺序是固定的,每个请求的索引对应目标列表的位置,直接通过索引赋值:

步骤1:定义组件内的列表变量

// 初始化各个列表
listNG: any[] = [];
listCodAML: any[] = [];
listTipoRating: any[] = [];
listProvince: any[] = [];
listGRA: any[] = [];
listFiliali: any[] = [];

步骤2:订阅时通过索引分配响应

from(req).pipe(
  concatMap((request, index) => request.pipe(
    map(resp => ({ data: resp, index }))
  ))
).subscribe(({ data, index }) => {
  switch(index) {
    case 0:
      this.listNG = data;
      break;
    case 1:
      this.listCodAML = data;
      break;
    case 2:
      this.listTipoRating = data;
      break;
    case 3:
      this.listProvince = data;
      break;
    case 4:
      this.listGRA = data;
      break;
    case 5:
      this.listFiliali = data;
      break;
  }
});

步骤3:HTML渲染同方法一

直接绑定对应的列表变量即可。

注意事项

  • concatMap会保证请求按数组顺序串行执行,每个请求完成后才发起下一个,因此响应的顺序和请求数组完全一致,索引匹配是可靠的。
  • 如果不需要严格的请求顺序,可以改用forkJoin并行发起请求,它会等待所有请求完成后一次性返回所有响应,同样可以通过数组索引分配到对应列表。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 18:20:31