javascript - 在 Angular 中执行前一个响应后执行一个函数

标签 javascript angular asynchronous async-await async.js

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

我希望我的服务仅在添加了 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';
      });


    });

但不幸的是它没有起作用。

最佳答案

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

不介意您使用async awaitdaisy chain风格与 new Promise 。自 async 版本 3.x 起框架,如果你不使用callback,你将能够使用令人惊叹的迭代函数(不知道是否全部)作为 promise 。 .

这是一个简单的示例,说明如何使用 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以另一种方便的方式。

关于javascript - 在 Angular 中执行前一个响应后执行一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59548122/

相关文章:

javascript - 在用户按下以 Bootstrap 模式提交表单后,如何显示成功消息?

javascript - 使用 Redux 的 store.getState() 和 store.dispatch() 进行更改而无需在 React 中订阅?

javascript - 异步回调不可能嵌套

spring-mvc - 在 Tomcat 8.5/Spring MVC 上设置异步处理超时

javascript - 在 Angular 2 子模块中强制服务实例化(AngularJS 运行 block 的替代方案)

带有异步 servlet 3.0 的 GWT requestbuilder

javascript - 按元素名称中的索引选择元素

javascript - 在下拉菜单中循环遍历年份

angular - HttpInterceptor 处理 401 错误不返回 Observable

angular - 每 X 秒调用一个函数