2017-06-26 74 views
2

我在for循环中订阅了一个for循环,它将JSON数据从外部源获取为一系列“类别数据”,然后根据用户筛选该数据当前位置。我需要的是等待所有订阅完成,然后才能继续执行我的应用。现在,它不会等待所有订阅完成,它只完成一些订阅,然后继续,而其他订阅在后台继续。如何在继续执行之前等待for循环中的订阅

我试过下面的“蛮力”方法,我知道一定数量的类别将被添加到过滤的数组中,并且它可以工作,但我不知道如何使它适用于任何情况。

这里是我的代码:

getMultipleCategoryData(categoryIds: string[]) { 
for (let i = 0; i < this.waypointIds.length; i++) { 
//after user selects their categories, its added to waypointNames, and occurences() gets the # of occurences of each waypoint name 
    let occurences = this.occurences(this.waypointNames[i], this.waypointNames); 
    this.categoryApi.getCategoryData(this.waypointIds[i]).toPromise().then(data => { 

    let filteredLocs = data.locations.filter(loc => this.distanceTo(loc, this.hbLoc) < MAX_RADIUS); 
    let foundLocs = []; 
    //fill filteredLocs with first n, n = occurences, entries of data 
    for (let n = 0; n < occurences; n++) { 
     if (filteredLocs[n] != undefined) { 
     foundLocs[n] = filteredLocs[n]; 
     } 
    } 
    //find locations closest to hbLoc (users current location), and add them to waypoints array 
    for (let j = 0; j < foundLocs.length; j++) { 
     for (let k = 0; k < filteredLocs.length; k++) { 
     if (this.distanceTo(this.hbLoc, filteredLocs[k]) < this.distanceTo(this.hbLoc, foundLocs[j]) && foundLocs.indexOf(filteredLocs[k]) < 0) { 
      foundLocs[j] = filteredLocs[k]; 
     } 
     } 
    } 
    if (foundLocs.length > 0 && foundLocs.indexOf(undefined) < 0) { 
     for (let m = 0; m < foundLocs.length; m++) { 
     this.waypointLocs.push(foundLocs[m]); 
     } 
    } 
    }).then(() => { 
    //this hardcoded, brute force method works, but i'd need it to be more elegant and dynamic 
    if (this.waypointLocs.length >= 5) { 
     let params = { waypointLocs: this.waypointLocs, hbLoc: this.hbLoc }; 
     this.navCtrl.push(MapPage, params); 
    } 
    }); 
} 
} 

而且categoryApi.getCategoryData方法:

getCategoryData(categoryId): Observable<any> { 
    // don't have data yet 
    return this.http.get(`${this.baseUrl}/category-data/${categoryId}.json`) 
     .map(response => { 
      this.categoryData[categoryId] = response.json(); 
      this.currentCategory = this.categoryData[categoryId]; 
      return this.currentCategory; 
     }); 
} 

一切工作正常,除了等待订阅完成,我真的很喜欢的方式来确定当所有订阅都完成时。任何帮助表示赞赏!

回答

2

您可以收集所有可观测的数组并用forkJoin等待它们全部完成:

let observables: Observable[] = []; 
for (let i = 0; i < this.waypointIds.length; i++) { 
    observables.push(this.categoryApi.getCategoryData(this.waypointIds[i])) 
} 
Observable.forkJoin(observables) 
    .subscribe(dataArray => { 
     // All observables in `observables` array have resolved and `dataArray` is an array of result of each observable 
    }); 
+0

大和简单的解决方案!像魅力一样工作。谢谢! – AlexT

相关问题