如何合并多个HTTP请求并合并结果

时间:2019-10-21 12:34:09

标签: http rxjs

我需要处理这样的情况:我有3个端点要调用,并且希望以最方便/最有效的方式获取数据。可以独立处理第一个调用,并返回单个结果。第二个端点返回一个集合,但需要在存在给定密钥的情况下发起0- *个后续调用。

理想情况下,我们希望从第二个端点调用中接收到该集合,作为包含第三个端点调用的结果的变异/新集合。

我当前正在使用forkJoin(observableA $,observableB $)并行处理前两个调用,但是我无法弄清楚如何包括顺序调用并将数据包含在observableB $中

//Customer observable
const customer$ = this._customerManagementService.getCustomer(
  accountNumber
);
 return forkJoin({
      customer: customer$,
      saleCycles: saleCyclesWithVehicle$
    }).pipe(finalize(() => this._loaderFactoryService.hide()));
 getSalesWithVehicle(accountNumber: string, dealerKey: string) {
    return this._salesCycleService
      .getCyclesForCustomer({
        customerNumber: accountNumber,
        dealerKey: dealerKey
      })
      .pipe(
        concatMap((results: ISaleCycle[]) => {
          return results.map(cycle => {
            return this._purchaseVehicleService.getPurchaseVehicle(
              cycle.vehicleKey
            );
          });
        })
      );
  }

我希望该集合将更多数据作为原始集合的新属性

UPDATE

经过一番思考,也许我应该在解决方案中的某个地方使用reduce。这样,我可以控制将哪些内容推送到数组中,并且它可以是动态的?

  getSalesWithVehicle(accountNumber: string, dealerKey: string) {
    return this._salesCycleService
      .getCyclesForCustomer({
        customerNumber: accountNumber,
        dealerKey: dealerKey
      })
      .pipe(
        switchMap((results: ISaleCycle[]) => {
          return results.map(cycle => {
            if (cycle.vehicleKey) {
              return this._purchaseVehicleService
                .getPurchaseVehicle(cycle.vehicleKey)
                .pipe(
                  reduce((acc, vehicle) => {
                    return { cycle: cycle, vehicle: vehicle };
                  }, []),
                  toArray()
                );
            }
            else {
              ///No extra data to be had
            }
          });
        }),
        concatAll()
      );
  }

2 个答案:

答案 0 :(得分:0)

我将使用public String update() { try { return update2(); } catch (Exception e) { return "Exception in update()"; } } @Transactional(rollbackFor = Exception.class) public String update2() throws Exception { List<Employee> l = repo.findAll(); for(int i=0 ; i<2 ; i++) { if(i==0) { l.get(i).setUsername("duplicate_value"); } else { l.get(i).setUsername("unique_value"); } repo.save(l.get(i)); } return "success"; } 合并HTTP请求2和3的响应。

concatMap()

如果您想查看上述运行,则进行了一次堆叠闪电战(请参阅控制台):https://stackblitz.com/edit/rxjs-nqi7f1

答案 1 :(得分:0)

这是我最终想出的解决方案。我接受了BoDeX的建议,并使用了concatMap()。在我看来,很明显,我想使用forkJoin并能够按对象键(即客户或saleCycles)引用结果。

在存在vehicleKey的情况下,我需要使用map()以定义的数据结构返回结果。同样,如果没有发现车辆,那么我只需要外部可观察到的东西。

const customer$ = this._customerManagementService.getCustomer(accountNumber);

const saleCyclesWithVehicle$ = this.getSalesWithVehicle(accountNumber,dealerKey);

getSalesWithVehicle(accountNumber: string, dealerKey: string) {
    return this._salesCycleService
      .getCyclesForCustomer({
        customerNumber: accountNumber,
        dealerKey: dealerKey
      })
      .pipe(
        concatMap(cycles => {
          return from(cycles).pipe(
            concatMap((cycle: ISaleCycle) => {
              if (cycle.vehicleKey) {
                return this._purchaseVehicleService
                  .getPurchaseVehicle(cycle.vehicleKey)
                  .pipe(
                    map(vehicle => {
                      return { cycle: cycle, vehicle: vehicle };
                    })
                  );
              } else {
                return of({ cycle: cycle });
              }
            }),
            toArray()
          );
        })
      );
  }

return forkJoin({
      customer: customer$,
      saleCycles: saleCyclesWithVehicle$
    }).pipe(finalize(() => this._loaderFactoryService.hide()));