【问题标题】:Execute a function after a response of previous in Angular在Angular中先前的响应之后执行一个函数
【发布时间】:2020-04-20 05:17:10
【问题描述】:

我正在尝试在前一个函数的成功响应返回后执行一个函数。一直在尝试,用不同的方法,但仍然是徒劳的。

我希望我的服务仅在添加 loanTerms(这是一个 API 调用)之后才发布 newLoan,但不会等待执行下一个函数而没有前一个响应。

在发布这个问题之前,我已经尝试了不同的方法,即使我将我的代码放在 subscribe 函数方法中。但我仍然没有按照我想要的方式执行。 问题是我有产品列表,我必须对每个产品执行网络操作,然后执行我的其他功能,但它只等待第一个产品,之后我不等待并执行下一个功能。 这是我的代码

{
    this.newLoanForm.value.invoiceDate = this.loanDate.format();
    document.getElementById('submitButton').style.display = 'none';

   
    // Adding number of months against give loan term ID
    let loanProducts = this.loanProductForm.value.products;
    let loanTerm;

    loanProducts.forEach(product => {
      this.loanTermService.getLoanTerm(product.loanTermId).subscribe((response: any) => {
        // console.log('Number of months: ', response.numberOfMonths)
        loanTerm = response.numberOfMonths;
        product.installmentStartDate = this.installmentStartDate.format();
        product.monthlyInstallment = product.total / loanTerm;

        // I want this function to executed after all the products have been completed their network activity, but it only waits for just 1st product, after that it executes the below code. how do I make it wait for all products.
        this.loanService.postLoan(this.newLoanForm.value).subscribe((response: any) => {

          console.log('Loan added successfully: ', response);
          PNotify.success({
            title: 'Loan added Successfully',
            text: 'Redirecting to list page',
            minHeight: '75px'
          })
          document.getElementById('submitButton').style.display = 'initial';
          this.router.navigate(['searchLoan']);

        }, (error) => {
          console.log('Error occured while adding loan: ', error);
          PNotify.error({
            title: 'Error occured while adding loan',
            text: 'Failed to add new loan',
            minHeight: '75px'
          })
          document.getElementById('submitButton').style.display = 'initial';
        })

      }, error => {
        console.log('Error while retrieving loanTermId: ', error);
      });
    });


    this.newLoanForm.value.loanProducts = loanProducts;
    console.log('Loan Products: ', this.loanProductForm.value);

以下是我使用 promise 和 asyncawait 尝试上述代码的方法

async calculateInstallments() {
    // Adding number of months against give loan term ID
    this.loanProducts = this.loanProductForm.value.products;
    // let loanTerm;

    this.loanProducts.forEach(async product => {
      console.log('Call to get loanTerms: ', await this.loanTermService.getLoanTermById(product.loanTermId));
      let response: any = await this.loanTermService.getLoanTermById(product.loanTermId);
      await this.loanProductService.getLoanProductByLoanId(product.loanTermId).then(() => {
        let loanTerm = response.numberOfMonths;
        console.log('loanTerms', loanTerm);
        product.installmentStartDate = this.installmentStartDate.format();
        product.monthlyInstallment = product.total / loanTerm;
      });

    });
  }
// putting the function I want to execute after the response of previous in the `then` method

    await this.calculateInstallments().then(() => {

      this.newLoanForm.value.loanProducts = this.loanProducts;
      // Posting loan after the response of loanTerms Service
      this.loanService.postLoan(this.newLoanForm.value).subscribe((response: any) => {

        console.log('Loan added successfully: ', response);
        PNotify.success({
          title: 'Loan added Successfully',
          text: 'Redirecting to list page',
          minHeight: '75px'
        });
        document.getElementById('submitButton').style.display = 'initial';
        this.router.navigate(['searchLoan']);

      }, (error) => {
        console.log('Error occured while adding loan: ', error);
        PNotify.error({
          title: 'Error occured while adding loan',
          text: 'Failed to add new loan',
          minHeight: '75px'
        });
        document.getElementById('submitButton').style.display = 'initial';
      });


    });

但不幸的是它没有工作。

【问题讨论】:

  • 我已经尝试过promise,但是没有成功
  • 你的async/awaitsn-p 很清楚你没有阅读我上面链接的问题。您不能像这样使用 forEach 来使异步函数等到每个产品都已处理完毕。使用正常循环。
  • 在这种情况下正常循环可以正常工作吗?
  • .forEach() 立即对数组的每个元素调用异步函数,而无需等待前一个元素完成。如果使用常规的for循环,则可以await在循环继续下一次迭代之前处理每个元素

标签: javascript angular asynchronous async-await async.js


【解决方案1】:

我今天刚刚answered a question,几乎同样的问题。也许您仍然需要解决方案,否则将其视为另一种方法。

不介意将async awaitdaisy chain 样式与new Promise 一起使用。从 async 框架的 3.x 版本开始,如果你不使用 callback,你将能够使用惊人的迭代函数(不知道是否全部)作为承诺。

这是一个简单的示例,说明如何将eachOf 函数用于异步任务。

const async = require('async');

let items = [
    { firstName: 'John', lastName: 'Doe' },
    { firstName: 'Jane', lastName: 'Doe' },
    { firstName: 'Me', lastName: 'Myself And I' }
];

async.eachOf(items, (item, index, callback) => {

    //here you could query db with vaulues from items array as item
    console.log('this is item:', item);

    new Promise(resolve => {
        setTimeout(() => {
            resolve(true);
        }, 500);
    })
    .then(result => {
       //maybe you need to do something else
       console.log('this is the result:', result);

       callback();
    });
})
.then(() => {
    //working ahead with daisy chain
    console.log('All items updated');
});

我希望您可以使用此设置,或者它是重组此设置并以另一种方便的方式使用 async await 的灵感。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 2017-09-12
    • 2021-02-12
    相关资源
    最近更新 更多