等待SUBSCRIBE块完成,然后再完成循环

时间:2020-07-23 09:06:27

标签: angular typescript

我正在使用循环重复调用API并将相应的响应打印到对象中,但是在完成第二个订阅之前,循环继续进行并执行下一行代码。如何在循环继续进行之前适当地等待订阅结束?

我希望在第二个循环开始之前将电话数组完全填充。

getData() {
this.finaldata=[];
this.phone=[];
this.api.getSingleValue('/API/shift/app_name/' + this.application_name).subscribe((Response: any) => {  
  if (Array.isArray(Response) && Response.length > 0) {
     for(let i=0; i<Response.length; i++){
        this.api.getSingleValue('/API/person/' + Response[i].qlid).subscribe((res: any) => {
        this.phone.push(res.contactNumber)   
      });  
    }
    console.log(this.phone)
    for(let i=0; i<Response.length; i++){
      this.object={
        "qlid": Response[i].qlid,
        "entry_Type": Response[i].entry_Type,
        "app_Name": Response[i].app_Name,
        "shift_Start_Time": Response[i].shift_Start_Time,
        "shift_End_Time":Response[i].shift_End_Time,
        "startDate": Response[i].startDate,
        "endDate": Response[i].endDate,
        "reason": Response[i].reason,
        "phone_no": this.phone[i]
      }
      this.finaldata.push(this.object);
    }
    console.log(this.finaldata)
    this.rowData = this.finaldata;
   
  }
  
  else{
    this.rowData=[];
    alert('No Data To Display')
    
  }
  
});

    
  }


}

1 个答案:

答案 0 :(得分:2)

尝试避免循环订阅和嵌套订阅。您可以使用RxJS运算符简化过程。

订阅工作流程:

  1. 调用this.api.getSingleValue('/API/shift/app_name/' + this.application_name)并使用switchMap将其切换为另一个可观察的状态。

  2. switchMap中,使用iif检查响应是否有效。

  3. 如果是,则将数组中的值映射到this.api.getSingleValue('/API/person/' + <response>.qlid))数组,并使用forkJoin合并可观察对象。使用map运算符可以进一步处理响应,将值推送到this.finaldata变量中并返回它。

  4. 如果不是,请使用throwError运算符引发错误。

  5. 在订阅中,分别使用this.finaldatanext回调处理响应(error变量)和错误。

尝试以下

getData() {
  this.finaldata = [];
  this.phone = [];
  this.api.getSingleValue('/API/shift/app_name/' + this.application_name).pipe(
    switchMap((Response: any) =>
      iif(
        () => Array.isArray(Response) && Response.length > 0,
        forkJoin(Response.map(res => this.api.getSingleValue('/API/person/' + res.qlid))).pipe(
          map(phone => {
            this.phone = phone.map(number => number.contactNumber);
            console.log(this.phone);
            for(let i=0; i < Response.length; i++){
              this.object = {
                "qlid": Response[i].qlid,
                "entry_Type": Response[i].entry_Type,
                "app_Name": Response[i].app_Name,
                "shift_Start_Time": Response[i].shift_Start_Time,
                "shift_End_Time":Response[i].shift_End_Time,
                "startDate": Response[i].startDate,
                "endDate": Response[i].endDate,
                "reason": Response[i].reason,
                "phone_no": this.phone[i]
              }
              this.finaldata.push(this.object);
            }
            console.log(this.finaldata);
            return this.finaldata;
          })
        ),
        throwError('Response was empty');
      )
    )
  ).subscribe(
    (finaldata: any) => {
      this.rowData = finaldata;
    },
    error => {
      this.rowData = [];
      alert('No Data To Display')
    }
  );
}

更新:删除rowData以外的成员变量

如果仅使用this.finaldatathis.phone来保存此函数中的信息,则可以将它们全部替换为局部变量。另外,您可以使用数组forEach函数,而不要手动循环数组。

getData() {
  this.api.getSingleValue('/API/shift/app_name/' + this.application_name).pipe(
    switchMap((Response: any) =>
      iif(
        () => Array.isArray(Response) && Response.length > 0,
        forkJoin(Response.map(res => this.api.getSingleValue('/API/person/' + res.qlid))).pipe(
          map(phones => {
            const contactNumbers = phones.map(phone => phone.contactNumber);
            let output = [];

            Response.forEach((res, index) => {
              output.push({
                "qlid": res.qlid,
                "entry_Type": res.entry_Type,
                "app_Name": res.app_Name,
                "shift_Start_Time": res.shift_Start_Time,
                "shift_End_Time":res.shift_End_Time,
                "startDate": res.startDate,
                "endDate": res.endDate,
                "reason": res.reason,
                "phone_no": contactNumbers[index]
              })
            });

            return output;
          })
        ),
        throwError('No Data To Display');
      )
    )
  ).subscribe(
    (finaldata: any) => {
      this.rowData = finaldata;
    },
    error => {
      this.rowData = [];
      alert(error)
    }
  );
}