我在for循环中有一个订阅,它从外部源获取
JSON数据作为一系列“类别数据”,然后根据用户当前位置过滤该数据.我需要的是等待所有订阅完成,然后才能继续我的应用程序.现在,它不等待所有订阅完成,它只完成一些订阅,然后继续,而其他订阅在后台继续.
我已经尝试了以下“强力”方法,我知道一定数量的类别将被添加到已过滤的数组中,并且它可以工作,但我不知道如何使其适用于任何情况.
这是我的代码:
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; }); }
一切都工作正常,除了等待订阅完成,我真的想要一种方法来确定所有订阅何时完成.任何帮助表示赞赏!
解决方法
您可以收集数组中的所有可观察对象并使用
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 });