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 作为一个整体阅读更多 - 它是您工具箱中的强大工具
我有一个问题。在我的程序中,我需要更新服务器上的一些记录,所以我需要在整个循环中执行此操作。毕竟我需要从服务器获取新信息。问题是我怎样才能等到所有 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()
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 作为一个整体阅读更多 - 它是您工具箱中的强大工具