Angular 2等待来自循环结束的所有http.put

时间:2017-04-24 08:45:53

标签: angular angular2-services

我有一个问题。在我的程序中,我需要在服务器上更新几条记录,所以我需要在循环中执行此操作。毕竟我需要从服务器获取新的信息。问题是我怎么能等到201的所有http.put响应?

现在有些代码: 我在服务中有一个更新功能:

public updateDataonServer(rodz: string, id: number, bodyContent: any) {
let body = JSON.stringify(bodyContent);
let headers = new Headers({ 'Content-Type': 'application/json' });
this.currentUser.setHttpHeader(headers);

let options = new RequestOptions({ headers: headers });

return this._http.put(serverAdress + '/rin/' + rodz + '/' + id,
  body,
  options).map(res => res.status).catch(this.handleError);

}

我在这个函数中使用它:

changeShow(showId: number, oldShow: MpGruppedGroup[]) {
    for (var show of oldShow) {

        var paramsDict = {
            'DAILY_PLAN_GROUP_ID': show.dailyPlanGroupId,
            'DAILY_AIRINGS': show.dailyAirings,
            'SHOW_ID': showId
        };

        this.manager.updateDataonServer('MP_GROUPED', show.dailyPlanGroupId, paramsDict).subscribe((data: any) => {
            console.log('status ', data);
        });
    }


    // that should be done after all updates return 201 status
    this.getShowDayGroups(showId);
}

2 个答案:

答案 0 :(得分:2)

您可以使用RxJS来实现您想要的目标:

 //extracts the params needed for the put request,
 // and returns the result of http.put 
 // it DOES NOT subscribe to the http.put
updateSingleShowOnServer(show) {
   ....
   // use this function to encapsulate extracting the values from
   // your 'show' object and constructing your http.put request
}

// accepts an array of 'shows' and 
// returns an observable that emits after every single put request
// has returned a value
updateMultipleShowsOnServer(shows) {

   // convert your array of shows into an array of put requests to update shows
   let requests$ = shows.map( show => this.updateSingleShowOnServer(show) );

   // return an Observable that waits until each request in the requests array
   // outputs a value before emitting a value.
   // you are going to subscribe to the observable output from this method
   return Observable.combineLatest(requests$);
} 

我对你的方法名称进行了一些屠杀道歉,但我这样做是为了更好地向你解释这些方法在做什么。您可以在代码中使用自己的名字。

但是,使用这些方法,您的changeShow变为:

changeShow(showId: number, oldShow: MpGruppedGroup[]) {

    // IMPORTANT - if any put request fails, this combined request will also fail, 
    // so you might want an error handler on your subscribe
    updateMultipleShowsOnServer(oldShow).subscribe(results => {

       // result is an array of the results of all put requests.
       this.getShowDayGroups(showId);         
   }, errors => {

       // Optional - do something if you got an error in one of the requests
   })

}

额外注意

  • 不要忘记使用`import' rxjs / add / observable / combineLatest'

  • 导入Observable.combineLatest
  • combineLatest将在这里工作,因为每个http请求只能发出一次http请求。 但是,如果每个可观测量有多个发射量,zip可能是更好的运算符。 我倾向于赞成combineLatest,因为它往往更有用。您应该阅读两位运营商以了解其中的差异。

  • 如果第二点没有意义,请将RxJS作为一个整体阅读 - 它是您工具箱中的强大工具

答案 1 :(得分:1)

您可以使用async/await。首先将updateDataonServer标记为异步并更改http的调用方式如下:

public async updateDataonServer(rodz: string, id: number, bodyContent: any) : Promise<any> {
let body = JSON.stringify(bodyContent);
let headers = new Headers({ 'Content-Type': 'application/json' });
this.currentUser.setHttpHeader(headers);

let options = new RequestOptions({ headers: headers });

const res = await this._http.put(serverAdress + '/rin/' + rodz + '/' + id,
  body,
  options).toPromise();
return   res.status;
}

然后,按then()

获取回报
changeShow(showId: number, oldShow: MpGruppedGroup[]) {
    for (var show of oldShow) {

        var paramsDict = {
            'DAILY_PLAN_GROUP_ID': show.dailyPlanGroupId,
            'DAILY_AIRINGS': show.dailyAirings,
            'SHOW_ID': showId
        };

      this.manager.updateDataonServer('MP_GROUPED', show.dailyPlanGroupId,
            paramsDict).then(data=> console.log('status ', data));


    }


    // that should be done after all updates return 201 status
    this.getShowDayGroups(showId);
}

请参阅this如果您在将HTTP观察信息转换为承诺时遇到问题,请查看此answer