Rxjs 如何使concatMap嵌套
我需要获取数组中每个起始日期的一系列数据 我需要按顺序获得它们,所以我使用concatMap来查看我的可观察日期,当我获得第一组值时,一切都很顺利Rxjs 如何使concatMap嵌套,rxjs,rxjs-observables,concatmap,Rxjs,Rxjs Observables,Concatmap,我需要获取数组中每个起始日期的一系列数据 我需要按顺序获得它们,所以我使用concatMap来查看我的可观察日期,当我获得第一组值时,一切都很顺利 of(...this.etiquetasEjeX) .pipe( concatMap(item=> this.dataService.getGastadoRealizadoEnMesYAño(this.proyectoId, getMonthNumber(item.slice(0,item.leng
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个数组,然后为一个图提供数据,我不知道如何按既定顺序添加更多调用
有什么想法吗
谢谢不确定这是否回答了您的问题(无法发表评论询问具体情况)。但假设其他后端调用也仅依赖于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提供的结果数组的大小,给定的解决方案可能会非常耗时和占用内存。谢谢@kruschild,我已经在subscribe()方法中填充了我的数组,但我需要对它们应用一系列逻辑,以获得基于这些,其他阵列和要执行此逻辑,我需要访问日期的值,在订阅中,我已经丢失了它,如果我尝试访问我计算未定义的函数之外的阵列感谢specs@kintela,我根据您提供的其他信息更新了我的答案谢谢,@kruschild这个新的有趣的答案帮助我找到了另一个场景,但在我的情况下,后续请求并不取决于先前请求的结果。一旦我将所有响应压缩并填充数组。我需要使用该阵列来获得另一个阵列。这些数组是我的组件类的属性,因此可以从任何方法访问,但如果我尝试从填充它们的方法外部访问,但对服务器调用的异步性尚未填充它们,我知道这是我的示例代码:我很高兴帮助您@kintela。你能用你的新代码创建一个新问题吗?我相信社区会很快为您提供好的解决方案。;-)