首页 > 解决方案 > 将所有响应合并到来自 forEach 的单个可观察对象?

问题描述

我需要对数组中的每个元素进行 REST API 调用。将它收集到单个 Observable 中的最有效方法是什么?服务器的响应是一个对象数组。我只需要一个数组而不是对象数组。因为它返回那个。有任何想法吗?

我目前的方法是:

  getDocumentsByGroupId() {
    this.form.formGroups.forEach(group =>
      this.documentService.findApprovedDocumentsUsingGET(this.possibility.DOCUMENT_FORM_GROUP, group.id.toString(), 'body', false, false)
        .subscribe(documents => this.documentList.push(documents)));
  }

标签: angularrxjs

解决方案


forkJoin如果您想并行订阅多个 observable,请使用。

getDocumentsByGroupId() {
  // create an array of observables - won't be run until subscribe is called
  const observables = this.form.formGroups
    .map(group => this.mapGroupToObservable(group));

  forkJoin(observables).subscribe(documents => {
    // documents will be an array of all the responses
    console.log(documents);
    // [ ... ]
  });
}

private mapGroupToObservable(group) {
  return this.documentService
   .findApprovedDocumentsUsingGET(this.possibility.DOCUMENT_FORM_GROUP,
     group.id.toString(), 'body', false, false)
}

forkJoin将并行运行所有可观察对象,并在最后一个返回时调用您的订阅回调。

为了更容易理解答案,我已将您的代码拆分以保持设置清洁。

我通常也会输入函数和变量,但我不确定你的类型。

展平响应对象

如果要将数组数组转换为平面数组,可以使用.flat().reduce().

平坦的

没有 IE 支持 - 需要 polyfill

const flattened = documents.flat();

减少

const flattened = documents.reduce((acc, val) => acc.concat(val), []);

reduce 示例直接取自MDN 文档 for flat


推荐阅读