【问题标题】:How to I make sure a certain function gets executed after another in Angular?如何确保某个函数在 Angular 中一个接一个地执行?
【发布时间】:2021-09-12 09:46:02
【问题描述】:

我目前正在尝试实现一个会员门户,当我提交表单时,我想发布会员并立即从输入的 ID 号中检索会员的价值。

我的提交函数如下:

submitForm() {
    const data = this.memberForm.value;
    console.log(data);
    this.service.postNewMember(data.title, data.firstname, data.surname, data.telRes, data.faxNbr, data.email, data.idNbr);
      
    this.service.getMember(data.idNbr).subscribe((res: any) => {
        console.log(res);
    }, (err: any) => {
        console.log(err);
    });
}

我的服务中的两个功能如下:

getMember(idNbr: string) {
    return this.http.get(this.url + '/crm/getMember/'+ idNbr)
}

postNewMember(title: string, firstName: string, surName: string, telRes: string, faxNbr: string, email: string, idNbr: string) {
    const headers = new HttpHeaders().set('Content-Type', 'application/json');

    const newMember = {
      title: title,
      firstName: firstName,
      surName: surName,
      telRes: telRes,
      faxNbr: faxNbr,
      email: email,
      idNbr: idNbr
    }

    this.http.post(this.url + '/crm/postNewMember', JSON.stringify(newMember), { headers: headers }).subscribe((res: any) => {
      console.log(res);
    })
    
}

我已经分别测试了这两个服务调用,它们都运行良好,但往往会发生 get 方法 get 在 post 方法完成执行之前调用,因此我在控制台中记录了一个错误,同时根据需要插入的数据。但是我需要 get 方法数据来对其执行进一步的操作,因此我需要在 post 方法之后执行它。

如何确保 service.getMember() 在 service.postNewMember() 之后执行?

【问题讨论】:

  • 为什么不传递一个对象而不是向postNewMember发送7或9个参数?重构该函数

标签: angular angular-http


【解决方案1】:

首先让你的 postNewMember 返回一个 observable

getMember(idNbr: string) {
    return this.http.get(this.url + '/crm/getMember/'+ idNbr)
}

postNewMember(title: string, firstName: string, surName: string, telRes: string, faxNbr: string, email: string, idNbr: string) {
    const headers = new HttpHeaders().set('Content-Type', 'application/json');

    const newMember = {
      title: title,
      firstName: firstName,
      surName: surName,
      telRes: telRes,
      faxNbr: faxNbr,
      email: email,
      idNbr: idNbr
    }

    return this.http.post(this.url + '/crm/postNewMember', JSON.stringify(newMember), { headers: headers });        
}

然后当你调用它时,使用订阅来调用getMember

    submitForm() {
        const data = this.memberForm.value;
        console.log(data);
        this.service.postNewMember(data.title, data.firstname, data.surname, data.telRes, data.faxNbr, data.email, data.idNbr).subscribe( (res) => {

      this.service.getMember(data.idNbr).subscribe((res2: any) => {
            console.log(res2);
        }, (err: any) => {
            console.log(err);
        });
 });
    }

【讨论】:

    【解决方案2】:

    HTTPClient 方法返回Observables 并使用RxJS 实现。要处理这些结果,您可以使用 RxJS 中的 pipe 运算符将调用链接在一起,将返回值从一个函数传递到另一个函数,而无需订阅。来自Angular documentation

    您可以使用管道将运算符链接在一起。管道让您可以将多个函数组合成一个函数。 pipe() 函数将要组合的函数作为其参数,并返回一个新函数,该函数在执行时会按顺序运行组合函数。

    在 OP 的描述中,没有描述错误处理的细节,所以这个答案会保持简单,并使用 finalize 作为保证顺序的一种方式。在实践中,您可能希望使用其他一些运算符,例如 catchError。我推荐operator decision tree 作为快速指南。

    首先让我们更改您的 postNewMember 调用,使其直接返回 observable。订阅不返回一个。

    postNewMember(title: string, firstName: string, surName: string, telRes: string, faxNbr: string, email: string, idNbr: string) {
      const headers = new HttpHeaders().set('Content-Type', 'application/json');
    
      const newMember = {
        title: title,
        firstName: firstName,
        surName: surName,
        telRes: telRes,
        faxNbr: faxNbr,
        email: email,
        idNbr: idNbr
      }
    
      return this.http.post(this.url + '/crm/postNewMember', JSON.stringify(newMember), { headers: headers });
    
    }
    

    现在让我们也想象一下您的服务中的 postThenGet 函数。我不会重新列出您的函数的所有参数。

    postThenGet(...args /*all the data fields you'd like*/, idNbr: string) {
      return this.service.postNewMembers(.../*all the arguments postNewMembers takes*/).pipe(
        finalize(this.service.getMember(idNbr)
      );
    }
    

    重要提示,这些 不是 Angular 提供的管道。这特别是一个 RxJS 构造。 Angular 遵循 RxJS 库,因此您也可以使用它,它的文档为较小的示例提供了很多详细信息。

    然后在你的组件或服务中使用 submitForm() 方法

    submitForm() {
      const data = this.memberForm.value;
      console.log(data);
      this.service.postThenGet(data.title, data.firstname, data.surname, data.telRes, data.faxNbr, data.email, data.idNbr).subscribe(
      /* From how finalize was used, this will return the result of the get operator */
      (res: any) => {
          console.log(res);
      }, (err: any) => {
          console.log(err);
      });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-22
      • 1970-01-01
      • 1970-01-01
      • 2014-02-07
      • 2013-12-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多