如何使 concatMap 嵌套

问题描述

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

array

我需要按顺序获取它们,所以我使用 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 数组

gastorealizado

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

有什么想法吗?

谢谢

解决方法

不确定这是否能回答您的问题(无法发表评论以询问具体细节)。但假设其他后端调用也仅依赖于 const readline = require('readline').createInterface({ input: process.stdin,output: process.stdout }); readline.on('line',(input) => { useCommand(input); }); function useCommand (input) { switch (input) { case "show userlist": CMD_showUserlist(); break; } } 中的元素,您可以使用 this.etiquetasEjeX 运算符。但是,关于 zip 的使用,每个项目将同时执行四个请求。如果您一次只能调用一个 api,则此解决方案需要进行一些调整。

concatMap

编辑:

好的,您在评论中提到后续请求取决于先前请求的结果。正如您在以下示例中看到的那样,像您最初请求的那样嵌套 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)
                    )
                  )
                )
              )
            )
          )
        )
      )
    ),)
  .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,itemC]) => combineLatest( of([...prevItems,itemC]),this.dataService.getD(itemC,map(([item,itemD]) => this.getGraph(item,itemD) ),) .subscribe(graphs => { // update the state of your object eg. this.myGraphs = graphs; }); 。这意味着在所有 api 调用完成之前,您的 observable 不会为您提供任何中间结果。根据您的 api 提供的结果数组的大小,给定的解决方案可能会消耗大量时间和内存。