【问题标题】:Angular 2 wait for all http.put from loop endAngular 2 等待来自循环结束的所有 http.put
【发布时间】:2017-09-14 14:00:21
【问题描述】:

我有一个问题。在我的程序中,我需要更新服务器上的一些记录,所以我需要通过循环来执行此操作。毕竟我需要从服务器获取新的信息。问题是我如何才能等到所有 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);
}

【问题讨论】:

    标签: angular angular2-services


    【解决方案1】:

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

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

    【讨论】:

    • 我喜欢这个答案,我想你也可以使用forkJoin。
    【解决方案2】:

    您可以使用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 observable 转换为 Promise 时遇到问题,请查看此answer

    【讨论】:

    • 已更新,因为 await 不能在异步函数之外使用
    猜你喜欢
    • 2021-11-20
    • 2022-01-16
    • 2021-03-02
    • 2020-06-01
    • 2021-11-03
    • 2020-03-13
    • 2021-12-15
    • 1970-01-01
    • 2015-10-25
    相关资源
    最近更新 更多