我需要执行一个函数,该函数处理由一系列可观察订阅产生的数据,但只有在它完成创建我的对象之后。
这是我的链条:
getFilters() {
this.filterSvc.getCamps()
.subscribe(
c => {
this.filters = c;
for (let camp of this.filters) {
this.filterSvc.getBuildings(camp.id)
.subscribe(
b => {
camp.buildings = b;
for (let building of camp.buildings) {
this.filterSvc.getFloors(building.id)
.subscribe(f => {
building.floors = f
});
};
});
}
});
// ONLY DO THIS AFTER THE OBJECT IS HYDRATED
this.globals.setCampFilters(this.filters);
}
正如您所看到的,我需要从getCamps返回的每个项目创建一个订阅,并从每个结果中创建另一个等等...然后说完了之后,我想执行
setCampFilters(this.filters);
在我填充过滤器之前,我怎能等到所有营地都有建筑物,所有建筑物都有地板?
答案 0 :(得分:1)
我会使用flatMap
运算符和Object.forJoin
。这是一个示例:
getFilters() {
this.filterSvc.getCamps()
.flatMap(c => {
this.filters = c;
// Observables for all camps
return Observable.forkJoin(this.filters.map(camp => {
// Links camp with the result of getBuildings
return Observable.forkJoin([
Observable.of(camp),
this.filterSvc.getBuildings(camp.id)
]);
})
})
.map(results => {
// Map results and link buildings with camps
return results.map(result => {
let camp = result[0];
let buildings = result[1];
camp.buildings = buildings;
return camp;
});
})
.subscribe(camps => {
// ...
]);
请注意,您可以链接flatMap
运算符。
这篇文章让您感兴趣:
答案 1 :(得分:1)
window.getFilters = function() {
this.filterSvc.getCamps()
.do((c: any) => this.filters = c)
.flatMap((c: any) => Observable.from(c)) // convert from Observable<Array<Camp>> to Observable<Camp>
.flatMap((camp: any) => this.filterSvc.getBuildings(camp.id).do(b => camp.buildings = b))
.flatMap(b => Observable.from(b))
.flatMap((building: any) => this.filterSvc.getFloors(building.id).do(f => building.floors = f))
.subscribe(null, null, () => this.globals.setCampFilters(this.filters));
}
一系列flatMap将Observable从Observable转换为&lt; Array&lt; Camp&gt;&gt;到Observable&lt; Array&lt; Floor&gt;&gt;,你只需要在它的onComplete事件上调用this.globals.setCampFilters
。
编辑:我更新了代码以阻止Typescript编译器抱怨不兼容的类型。我添加: any
,我认为TS编译器会抱怨,您可以在:any
之前添加=>