0

我需要为数组中的每个原始日期获取一系列数据

大批

我需要按顺序获取它们,所以我使用 concatMap 来检查我的可观察日期,当我获得第一组值时,一切正常

of(...this.etiquetasEjeX)
  .pipe(
    concatMap(item=>
        this.dataService.getGastadoRealizadoEnMesYAño(this.proyectoId,
        getMonthNumber(item.slice(0,item.length-4)),
        +item.slice(-4),
        this.acumular)
        ),
    toArray()
  )
  .subscribe(item=>{
    this.gastadoRealizado=item;
    console.log('this.gastadoRealizado: ', this.gastadoRealizado);
  });

我有我的 this.gastoRealizado 数组

胃口大开

但我需要对后端进行 3 次以上调用以获得总共 4 个数组,然后提供一个图表,我不知道如何以这个既定顺序添加更多调用

请问有什么想法吗?

谢谢

4

1 回答 1

1

不确定这是否回答了您的问题(无法发表评论以询问具体情况)。但是假设其他后端调用也仅依赖于this.etiquetasEjeX您可以使用zip运算符的元素。然而,关于concatMap四个请求的使用,每个项目将同时执行。如果您一次只能调用一个 api,则此解决方案需要进行一些调整。

import { of, zip } from 'rxjs';
import { concatMap, toArray } from 'rxjs/operators';

//...

of(...this.etiquetasEjeX)
  .pipe(
    concatMap(item=>
        zip(
            this.dataService.getGastadoRealizadoEnMesYAño(...),
            this.dataService.getB...,
            this.dataService.getC...,
            this.dataService.getD...,
        ),
    toArray(),
  )
  .subscribe((arr: [ItemA, ItemB, ItemC, ItemD][])=> {
    //...
  });

编辑:

好的,您在评论中提到后续请求取决于先前请求的结果。concatMap正如您在以下示例中所见,像您最初请求的嵌套操作会有点混乱:

of(...this.etiquetasEjeX)
  .pipe(
    concatMap(item=>
      this.dataService.getGastadoRealizadoEnMesYAño(...).pipe(
        concatMap(itemA =>
          this.dataService.getB(itemA).pipe(
            concatMap(itemB =>
              this.dataService.getC(itemB).pipe(
                concatMap(itemC =>
                  this.dataService.getD(itemC).pipe(
                    map(itemD =>
                      // every combination of items would be available here
                      this.getGraph(item, itemA, itemB, itemC, itemD)
                    )
                  )
                )
              )
            )
          )
        )
      )
    ),
    toArray(),
  )
  .subscribe(graphs => {
    // graphs array contains elements that were returned by this.getGraph 
  });

但是也可以按顺序调用相同的操作,而不会丢失提供图形所需的中间结果:

of(...this.etiquetasEjeX)
  .pipe(
    concatMap(item=> combineLatest(
      of(item),
      this.dataService.getA(item, ...),
    )),
    concatMap(([item, itemA]) =>
      this.dataService.getB(itemA, ...)
combineLatest(
      of([item, itemA]), // it's important that the elements are enclosed inside an array here otherwise the of operator fires twice and doesn't have the proper effect
      ,
    )),
    concatMap(([prevItems, itemB]) => combineLatest(
      of([...prevItems, itemB]),
      this.dataService.getC(itemB, ...),
    )),
    concatMap(([prevItems, itemC]) => combineLatest(
      of([...prevItems, itemC]),
      this.dataService.getD(itemC, ...),
    )),
    map(([item, itemA, itemB, itemC, itemD]) =>
      this.getGraph(item, itemA, itemB, itemC, itemD)
    ),
    toArray(),
  )
  .subscribe(graphs => {
    // update the state of your object eg.
    this.myGraphs = graphs;
  });

我注意到您正在使用toArray. 这意味着在您完成所有 api 调用之前,您的 observable 不会为您提供任何中间结果。根据您的 api 提供的结果数组的大小,给定的解决方案可能会耗费大量时间和内存。

于 2021-03-10T10:16:52.550 回答