如何确保某个函数在 Angular 中一个接一个地执行?

How to I make sure a certain function gets executed after another in Angular?

我目前正在尝试实现一个会员门户,当我在其中提交表单时,我想 post 会员并立即从输入的 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);
    })
    
}

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

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

首先让你的postNewMember成为return一个可观察的

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

HTTPClient 方法 returns Observables and uses the RxJS implementation. To handle the results of these, you can chain your calls together using the pipe operator from RxJS to pass the return values from one function to another without having to subscribe. From the Angular documentation

You can use pipes to link operators together. Pipes let you combine multiple functions into a single function. The pipe() function takes as its arguments the functions you want to combine, and returns a new function that, when executed, runs the composed functions in sequence.

在 OP 描述的内容中,没有描述错误处理的细节,所以这个答案将保持简单,并使用 finalize 作为保证顺序的方法。在实践中,您可能希望使用其他一些运算符,例如 catchError. I'd recommend the operator decision tree 作为快速指南。

首先让我们更改您的 postNewMember 调用,使其 return 直接成为可观察对象。订阅没有 return 一个。

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