简体   繁体   English

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

[英]Wait for Promise before calling another promise from inside a for loop - Angular

Problem: I need to call an API one after the other from inside the for loop. 问题:我需要从for循环中一个接一个地调用API。 I need to wait for former API to resolve before calling the latter one. 我需要等待前一个API解析后才能调用后一个。

I am calling a Get API inside a for loop which generate Document on server side , as shown below 我正在for循环内调用Get 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";
  }

And

 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();
    })
  }

when I call callGeneratePDFAPI() inside foor loop and send parameter one by one than it hit the API in Async , Means it does not wait for first call to finish before making another http call , 当我在foor循环中调用callGeneratePDFAPI()并逐个发送参数(而不是在Async中的API上)时,这意味着在进行另一个http调用之前,它不等待第一次调用完成,

Idea to solve this was to use promise as 解决这个问题的想法是使用promise作为

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

And then 接着

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

But how can I use it inside for loop , I have to make request 10 times so I can show user that out of 10 , n number of document has been created . 但是我如何在for循环中使用它,我必须发出10次请求,这样我才能向用户展示已经创建了10个n个文档。

How to use sync api call instead of by default async call in angular 如何在角度中使用同步API调用而不是默认情况下的异步调用

Update 1 更新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";

} }

You can use async/await. 您可以使用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;
  }

Update 1:- 更新1:-

To make requests synchronously, try the below idea. 要同步发出请求,请尝试以下想法。

 [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) }) }; 


You can use Promise.all method. 您可以使用Promise.all方法。

Run your for loop and collect promises in an array promises . 运行for循环并以数组promises收集promises Then call the below code:- 然后调用以下代码:

var promises = [];

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

For a live example, refer here 有关实时示例,请参见此处


Please note then will fire once all the promises resolve and you will get all the data in an array. 请注意,一旦所有的承诺都解决了, then它将触发,您将获得数组中的所有数据。 If any of the promise rejects, then you need to catch it. 如果任何承诺被拒绝,那么您就必须兑现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM