可观察订阅链完成后执行函数(Angular 2)

时间:2016-07-07 17:45:00

标签: angularjs typescript angular promise observable

我需要执行一个函数,该函数处理由一系列可观察订阅产生的数据,但只有在它完成创建我的对象之后。

这是我的链条:

 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);

在我填充过滤器之前,我怎能等到所有营地都有建筑物,所有建筑物都有地板?

2 个答案:

答案 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之前添加=>