等待Promise,然后从for循环中调用另一个promise-Angular

时间:2018-08-22 10:36:25

标签: angular angular5

问题:我需要在for循环中一个接一个地调用API。我需要等待前一个API解析后才能调用后一个。

我正在for循环内调用Get API,该API在服务器端生成Document,如下所示

 async ExtendedMethod() {
    let MList: PendingListMemberWise[] = [];
    for (let i = 0; i < this.MemberList.length; i++) {
      if (this.MemberList[i].checked) {
        MList.push(this.MemberList[i]);
      }
    }
    this.ShowLoader = true;
    for (let i = 0; i < MList.length; i++) {
      this.lblText = "Generating PDF " + i + "/" + MList.length;
    await this.callGeneratePDFAPI(MList[i]);
    }
    this.lblText = "PDF Generation Completed";
    this.GetBranchList();
    this.ShowLoader = false;
    //this.appconfig.Message="PDF Files have been Generated , Use the Download PDF Link to Download Them";
  }

还有

 callGeneratePDFAPI(mcodeList: PendingListMemberWise) {
    return new Promise((resolve, reject) => {
      var url = this.baseurl + 'api/GeneratePDF/GeneratePDF/' + mcodeList.memberCode + '/' + sessionStorage.getItem("UserID");
      this.http.get(url)
        .subscribe(result => {
          var index = this.MemberList.indexOf(mcodeList);
          if (index > -1) {
            this.MemberList.splice(index, 1);
          }
        }, error => {
          console.error(error);
        });
      resolve();
    })
  }

当我在foor循环中调用callGeneratePDFAPI()并逐个发送参数(而不是在Async中的API上发送参数)时,这意味着在进行另一个http调用之前,它不等待第一个调用完成,

解决此问题的想法是将promise用作

    TestMethod() {
    try {
      return new Promise((resolve, reject) => {
        //Some Code here
        resolve();
      })
    } catch (error) {
      console.log(error);
    }
  }

然后

 this.TestMethod()).then(() => {
      //Another task to do after TestMethod return 
    });

但是如何在循环中使用它,我必须发出10次请求,以便向用户显示已经创建了10个文档中的n个。

如何使用同步api调用代替默认的Angular异步调用

更新1

ExtendedMethod() {
let MList: PendingListMemberWise[] = [];
for (let i = 0; i < this.MemberList.length; i++) {
  if (this.MemberList[i].checked) {
    MList.push(this.MemberList[i]);
  }
}
this.ShowLoader = true;
var promises = [];
for (let i = 0; i < MList.length; i++) {
  this.lblText = "Generating PDF " + i + "/" + MList.length;
  promises.push(this.callGeneratePDFAPI(MList[i]));
}
Promise.all(promises)
  .then((response) => {console.log('All Done') });
this.lblText = "PDF Generation Completed";
this.GetBranchList();
this.ShowLoader = false;
//this.appconfig.Message="PDF Files have been Generated , Use the Download PDF Link to Download Them";

}

2 个答案:

答案 0 :(得分:2)

您可以使用async / await。

**async** ExtendedMethod() {
    let MList: PendingListMemberWise[] = [];
    for (let i = 0; i < this.MemberList.length; i++) {
      if (this.MemberList[i].checked) {
        MList.push(this.MemberList[i]);
      }
    }
    this.ShowLoader = true;
    for (let i = 0; i < MList.length; i++) {
      this.lblText = "Generating PDF " + i + "/" + MList.length;
      **await** this.callGeneratePDFAPI(MList[i]);
    }
    this.lblText = "PDF Generation Completed";
    this.GetBranchList();
    this.ShowLoader = false;
    //this.appconfig.Message="PDF Files have been Generated , Use the Download PDF Link to Download Them";
  }

  callGeneratePDFAPI(mcodeList: PendingListMemberWise) {
    var url = this.baseurl + 'api/GeneratePDF/GeneratePDF/' + mcodeList.memberCode + '/' + sessionStorage.getItem("UserID");
    const service = this.http.get(url).toPromise();
    service.then(result => {
        var index = this.MemberList.indexOf(mcodeList);
        if (index > -1) {
          this.MemberList.splice(index, 1);
        }
      })
      .catch(error => {
        console.error(error);
      });
      return service;
  }

答案 1 :(得分:1)

更新1:-

要同步发出请求,请尝试以下想法。

[1,2,3,4,5].reduce((acc, element, index) => {
  return acc.then(() => {
    console.log('Generating PDF: ', index + 1);
    return callGeneratePDFAPI();
  })
}, Promise.resolve());

function callGeneratePDFAPI(){
  return new Promise((resolve) => {
    setTimeout(()=> {
      resolve();
    }, 2000)
  })
};


您可以使用Promise.all方法。

运行for循环并在数组promises中收集promise。然后调用以下代码:-

var promises = [];

<your_array>.forEach(element => {
  // push into promises
})
Promise.all(promises)
  .then((response) => {});

有关实时示例,请参考here


请注意,then将在所有的承诺都解决后触发,您将获得数组中的所有数据。如果任何承诺被拒绝,那么您就必须兑现。