如何异步调用方法并等待API调用完成

时间:2019-08-19 17:07:14

标签: javascript angular typescript observable subscribe

我是新手,在创建两个组件学生组件父母组件的场景中:

我为学生的所有RESTAPI服务在 studentHttpService 类中创建了单独的函数文件,并且我有一种方法:

SaveOrUpdateStudent(studentDetail: IStudentDetail): Observable<IStudentDetail> {
    return this.http.post<IStudentDetail>(this.serverurl + '/api/studentdata/SaveOrUpdateStudent', studentDetail);
}



学生组件中调用上述服务,其中方法SaveStudent()检查所有必需的验证,然后调用studentHttpService.SaveOrUpdateStudent(studentDetail)

这对于学生组件来说很好用。

对于父组件,我也做了类似的事情:

parentHttpService 类中为父母的所有RESTAPI服务创建了单独的函数文件:

SaveOrUpdateParent(parentDetail: IParentDetail): Observable<IParentDetail> {
    return this.http.post<IParentDetail>(this.serverurl + '/api/parentdata/SaveOrUpdateParent', parentDetail);
}



现在我的问题是,在“父级”组件中,我有一个部分来创建新的父级,并且在创建时有一个下拉列表,用于从学生列表中选择一个学生,并在保存父级详细信息时,所选学生链接到了父级。使用下拉功能,我在下拉菜单旁边还有一个按钮,可以创建一个新学生,然后单击该按钮将以模式打开学生组件(该模式允许用户仅输入新的学生详细信息,当用户使用时不应保存该详细信息单击“模态”的“确定”按钮),并且我在父组件中使用了与子组件相同的学生组件。当用户单击“确定”按钮填充学生的详细信息后,它将在学生下拉列表中填充新创建的学生的姓名以及当前选择的值

当我为父母保存详细信息时,它应该保存新创建的学生和父母详细信息,并将新创建的学生也链接到父母。

为此,我尝试使用async / await,其中:

我用过:

@ViewChild(StudentDetail) studentDetail: StudentDetail;

async SaveParent(): Promise<void> {
    if(newStudentCreated) {
        await studentDetail.SaveStudent();
    }
    await parentHttpService.SaveOrUpdateParent(parentDetail);
}

在我的父组件类中

因此,如果我调试并检查它可以正常工作,并且新学生已链接到Parent。 但是有时,当花费更多时间保存学生数据时,它不会链接。我尝试使用:

SaveParent(): Promise<void> {
return new Promise((resolve) => {
    if(newStudentCreated) {
         studentDetail.SaveStudent();
    } 
    resolve();
    }).then(()=> {
     parentHttpService.saveOrUpdateParent(parentDetail)
     });
}



它也有同样的问题。使用类似的技术帮助我朝正确的方向努力。

2 个答案:

答案 0 :(得分:1)

为什么不使用switchMap?

parentHttpService.saveOrUpdateStudent(studentDetail: IStudentDetail).pipe(
   switchMap(res=>{
      ..here you has the response of saveStudent
      ..I supouse you want to change "parentDetail", with the response
      ..e.g. if return a studentId, you can write some like
      parentDetail.studentId=res.studentId
      return parentHttpService.saveOrUpdateParent(parentDetail)
   })).subscribe(res=>{
      ..here the response of saveParent..
   })

答案 1 :(得分:0)

您不需要在这里异步或等待。您可以执行以下操作(简化了一点,可能需要做一些工作):

saveStudentAndParent(): void {
    studentDetail.saveStudent().pipe(takeUntil(this._destroy$)).subscribe(
        data => this.saveParent(data),
        err => console.log(err)
    )
}

saveParent(data: any): void {
  // Do your check if the student saved successfully then save parent
}

您会注意到我正在使用takeUntil来确保订阅已取消订阅,这需要花点时间才能使我能够开始工作,但是非常简单。您所需要做的就是设置一个名为destroy $的Subject并在ngOnDestroy调用

this._destroy$.next(true);
this._destroy$.complete();

在保存学生电话的订阅中调用saveParent可以确保在继续进行之前完成学生电话。