如何在循环中等待Http请求完成执行以便继续执行某些相关的代码?

时间:2019-07-04 07:39:02

标签: http promise angular7

我需要进行API调用(主API调用),这取决于其他几个API调用(子调用)的结果,但是我无法做到理想,因为此时子调用的结果将不可用由于异步执行,我进行了Main api调用。

这是我的代码(我一直在尝试)-

Http服务功能-

async fetchShift(shiftName: string): Promise<any> {

const res = await this.httpClient.get(this.systemConfig.UIBACKEND_API_URL + '/api/v1/shift/find/' + shiftName).toPromise();
return res;
}

中间功能-

async formAssociateProduct(sheetAllRows): Promise<any> {

var promise = new Promise((resolve, reject) => {
  for (let i: number = 0; i < sheetAllRows.length; i++) {
    //Child api calls
    this.fetchShift("A").then(data => {
      this.listOfAssociatedProduct.push(data);
    });
  }
  resolve();
});
return promise;

}

呼叫者功能-

upload(event) {
console.log(event);
var me = this;
var reader = new FileReader();
var file = event.target.files[0];
reader.onload = function (event) {
  var workbook = XLSX.read(event.target.result, {
    type: 'binary'
  });

  var sheetAllRows = XLSX.utils.sheet_to_json(workbook.Sheets["Sheet1"]);
   me.formAssociateProduct(sheetAllRows).then(
    data => {
      //Main Api Call
      me.httpClient.post(me.systemConfig.UIBACKEND_API_URL + '/api/v1/products/upload', me.listOfAssociatedProduct).subscribe(data => {

      });
    }
  );  };

reader.readAsBinaryString(file);
}

我在进行Main api调用所需的then()回调中发现列表为空。请帮忙。

1 个答案:

答案 0 :(得分:0)

这里有很多问题。以下是更改/注释的摘要:

  1. formAssociateProduct()中,您不等待所有异步调用完成后再解决返回的Promise。我建议使用Promise.all()来跟踪它们何时完成。而且,因为您没有使用async,所以拥有功能await也没有任何好处。您可以直接返回承诺。在对数组进行异步处理时,使用.map()并获得一个诺言数组通常会更干净,然后可以将它们提供给Promise.all()来知道它们何时完成。

  2. fetchShift()看起来可以正常工作,但是同样,没有理由将其标记为async,您可以直接返回承诺。

    < / li>
  3. upload()中,逻辑看起来基本上是正确的。我已将箭头函数切换为回调函数,因此可以直接使用this代替me。同样,该函数似乎需要在reader,对formAssociateProduct()的调用以及对主API的调用中进行错误处理。

  4. 您似乎在.subscribe()的最低级别混合了承诺和来自upload()的回调。这通常效果不佳,因为很难将完成,结果和错误回传给调用者。我不知道这些特定的API,也不知道您到底要在其中完成什么才能确切地了解建议。

这是固定的代码:

fetchShift(shiftName: string): Promise < any > {
    return this.httpClient.get(this.systemConfig.UIBACKEND_API_URL + '/api/v1/shift/find/' + shiftName).toPromise();
}

// call fetchShift on all the sheet rows
formAssociateProduct(sheetAllRows): Promise < any > {
    return Promise.all(sheetAllRows.map(row => {
        return this.fetchShift("A");
    })).then(results => {
        this.listOfAssociatedProduct = results;
    });
}

upload(event) {
    console.log(event);
    var reader = new FileReader();
    var file = event.target.files[0];
    reader.onload = (event) => {
        var workbook = XLSX.read(event.target.result, {
            type: 'binary'
        });

        var sheetAllRows = XLSX.utils.sheet_to_json(workbook.Sheets["Sheet1"]);
        // need lots of error handling here
        this.formAssociateProduct(sheetAllRows).then(data => {
            //Main Api Call
            return this.httpClient.post(me.systemConfig.UIBACKEND_API_URL + '/api/v1/products/upload',
                this.listOfAssociatedProduct).subscribe(data => {
                // some code here
            });
        });
    }
    // start reading the file
    reader.readAsBinaryString(file);
}