Angular4中的异步调用

时间:2018-09-20 01:39:08

标签: angular asynchronous

我可以肯定已经问过这个问题了,但是我也相信我的用例是完全不同的。

我正在使用Angular 4。 我有一个服务,它调用http获取请求以获取项目列表。 提取的每个项目都包含一个人的名字,姓氏和别名的数据。

因此,在我发出此请求的同时,我还需要对列表中的每个项目发送另一系列的http get请求,为每个项目发送名字,姓氏,dob,并获取地址并为列表中的每个项目设置地址在我的用户界面中。

我需要一种非阻塞的异步方式来处理它。

现在,这就是我的处理方式,我的UI会立即加载整个模板和第一项。然后,它会提取第二个api,并在填充第一个api中的其余项目之前更新该数据。

因此,页面的加载看起来确实不一致且缓慢。

请查看下面的代码并提出建议。

// the below service is the http request to get the list of items.

this._searchService.search(data).subscribe(
    resp => {
        this.loadaddressforeachitemindata(resp);
        this.onSuccess(resp);
    }, (error) => {
        this.loaderService.display(false);
        console.log("Error in search---"+error);
        this.errorMessage = "Internal Server Error, please try after some time ";
});  

onSuccess()方法获取响应并将数据设置为模型

onSuccess(data: Response) {
    this.results = this.service.buildResult( data.json().response);
    this._router.navigateByUrl('/dashboard/landing/(view:people/person/results)');
}

buildresult将数据设置为我的结果模型类,如下所示:

export class PersonResults {
    firstname?: any;
    lastname?: any[];
    dob?: any[];
    address: any[];
}

loadaddressforeachitem()方法包含一个for循环,以循环访问整个列表,从而对第一个http请求中提取的每个项目的数据集调用http get请求

loadaddressforeachitem(data:Response){
    for(let i = 0; i<numberofiteminlist ; i++){
        let rowdata = data.json().response.person[i]
        let firstname = rowdata.names.name.firstName;
        let lastname = rowdata.names.name.lastName;
        let dob = rowdata.DOBs.DOB;
        let addresssearchparams = ({ firstName : firstname, lastName : lastname, dob: appdob });
        this.service.getAddressData(addresssearchparams).subscribe(
            res => {
                this.service.storeaddressdata(res)
        })
    } // end of for loop
} // end of loadaddressforeachitem method

storeaddressdata()是服务中的一种方法,用于将为每个项目返回的地址推送到上述数据模型中的数组“地址”字段中。

1 个答案:

答案 0 :(得分:0)

我建议您等到获得一个人的addressInformation后,再一次更新UI,而不是等待获取每个项目的所有addressInformation。这样,用户将获得一个很好的逐个加载数据的体验,浏览器将不会等待所有异步调用完成。

为此,您不需要进行大的更改,只需将 loadaddressforeachitem 移到您的组件中,并在 getAddressData 订阅回调上更新UI的范围

loadaddressforeachitem(data:Response){
        for(let i = 0; i<numberofiteminlist ; i++){
             let rowdata = data.json().response.person[i]
                  let firstname = rowdata.names.name.firstName;
                  let lastname = rowdata.names.name.lastName;
                  let dob = rowdata.DOBs.DOB;
                  let addresssearchparams = ({ firstName : firstname, lastName : lastname, dob: appdob });
          this.service.getAddressData(addresssearchparams).subscribe(
            res => {
                 //here you can update the UI scope or append new address data in the scope 
          })
  } // end of for loop
} 

或者,如果您不想从服务中删除逻辑,则可以使用 RxJS Subject 将数据中的数据发送到组件中,以发送通知。从该组件中,您可以接收通知,并使用您作为参数传递的数据来更新UI。

https://blog.angularindepth.com/rxjs-understanding-subjects-5c585188c3e1

您还可以使用类似于RxJS Subject的Angular EventEmitter

https://angular.io/api/core/EventEmitter