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

Angular 2 wait for all http.put from loop end

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

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

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

您可以使用 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()

得到return
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 and in case you face an issue with converting the HTTP observable to promise, please have a look on this answer

你可以使用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 请求 observable 只发出一次。 但是,如果每个可观察对象有多个发射,zip 可能是更好的运算符。 我倾向于赞成 combineLatest 因为它往往更有用。您应该仔细阅读这两个运算符以了解它们之间的差异。

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