首页 > 解决方案 > 在循环中对同一 API 进行角度多次调用

问题描述

我需要遍历对象数组并为每个对象进行 API 调用。根据响应中的对象数量,我正在创建新对象并推入一个数组。下面是示例代码。例如,如果最初有 2 个提供者,每个提供者都有 2 个位置,那么updatedProviderList将有 4 个提供者。这工作正常。

问题是,updateProvidersInState只有在所有 API 调用和与之相关的逻辑都完成后才能调用。我已尝试使用如下所示的索引,但它不起作用。updateProvidersInState只有在所有 API 调用完成后才能调用?

let providers = []; //assume this is already populated
let updatedProvider;
let updatedProviderList;
providers.forEach((prv, index) => {
  this.dataService.getLocation(prv.id).subscribe((response: LocationResults) => {
    response.locations.forEach((location, i) => {
      updatedProvider = cloneDeep(prv);
      updatedProvider.location = location;
      updatedProviderList.push(updatedProvider);
      if (index === providers.length - 1 && i === response.length - 1) {
        this.updateProvidersInState(updatedProviderList);
      }
    });
  });
});

标签: angularrxjsobservable

解决方案


forkJoin()功能允许您加入可观察对象列表并在所有请求完成后继续。这样做的好处是请求将并行而不是顺序发出。

import { forkJoin } from 'rxjs';

let providers: Provider[] = []; // assume this is populated, i made up the type Provider.

forkJoin(
  providers.map(p =>
    this.dataService.getLocation(p.id).pipe(
      // map each Location to a cloned provider object
      map((response: Location[]) => response.map(location => {
        const updatedProvider = cloneDeep(p);
        updatedProvider.location = location;
        return updatedProvider;
      }))
    )
  )
).subscribe((p: Provider[][]) => {
  // flatten the multi-dimensional array
  const updatedProviders = [].concat(...p);

  this.updateProvidersInState(updatedProviders);
});

推荐阅读