这是交易:我有一个HTTP get请求,它返回一个JSON对象列表。使用RxJS我订阅接收该列表的数据。现在,对于该列表中的每个对象,我想执行另一个HTTP请求,然后将该请求的结果放在一个数组中。
到目前为止,我已经能够做到这一点,但我似乎无法弄清楚如何用数据维护初始列表的顺序。这可能与整个Observable机制是异步的事实有关。
这是我的代码:
ngOnInit(): void {
this.shiftInformationService.getShifts("2016-11-03T06:00:00Z", "2016-11-06T06:00:00Z")
.subscribe(shifts => {
shifts.forEach(shift => {
this.addDataToAreaChart(shift.startDateTime, shift.endDateTime, shift.description);
});
});
}
addDataToAreaChart(startDate: string, endDate: string, description: string) {
this.machineStatisticsService
.getCumulativeMachineStateDurations(startDate, endDate)
.subscribe(s => {
this.areaChartData = [];
this.areaChartData.push(new AreaChartData(startDate, endDate, description, s));
});
}
我想要的是在推送shifts.forEach
数组中的数据时保持从areaChartData
循环调用的顺序。
有什么想法吗?帮助将不胜感激!
更新:已解决!
最终代码:
ngOnInit(): void {
var startDate = new Date();
startDate.setDate(startDate.getDate() - 3);
this.shiftInformationService.getShifts(DateUtil.formatDate(startDate), DateUtil.formatDate(new Date()))
.subscribe(shifts => {
Observable.from(shifts)
.concatMap((shift) => {
return this.machineStatisticsService
.getCumulativeMachineStateDurations(shift.startDateTime, shift.endDateTime)
.map((result) => {
return {
"addDataToAreaChartValue": result,
"shift": shift
}
});
})
.subscribe(s => {
this.areaChartData = [];
this.areaChartData.push(
new AreaChartData(
s.shift.startDateTime,
s.shift.endDateTime,
s.shift.description + ' ' + s.shift.startDateTime.slice(5, 10),
s.addDataToAreaChartValue
)
);
});
});
}
感谢迈克尔!
答案 0 :(得分:4)
使用concatMap
按顺序处理。
将每个源值投影到一个Observable,它在输出Observable中合并,以序列化的方式等待每一个在合并下一个之前完成。
使用map
在observable中追加/转换值。
将一个给定的项目函数应用于源Observable发出的每个值,并将结果值作为Observable发出。
所以,你需要这样做
ngOnInit(): void {
this.shiftInformationService.getShifts("2016-11-03T06:00:00Z", "2016-11-06T06:00:00Z")
.subscribe(shifts => {
Rx.Observable.from(shifts) // create observable of each value in array
.concatMap((shift) => { // process in sequence
return this.addDataToAreaChart(
shift.startDateTime,
shift.endDateTime,
shift.description
).map((result) => {
return {
"addDataToAreaChartValue" : result, // addDataToAreaChart result
"shift": shift // append shift object here, so we can access it on subscribe
}
});
})
.subscribe(s => {
//this.areaChartData = []; // why??
this.areaChartData.push(
new AreaChartData(
s.shift.startDate,
s.shift.endDate,
s.shift.description,
s.addDataToAreaChartValue
)
);
});
});
}
addDataToAreaChart(startDate: string, endDate: string, description: string) {
return this.machineStatisticsService
getCumulativeMachineStateDurations(startDate, endDate);
}