【问题标题】:How to async call a method and wait for an API call to complete如何异步调用方法并等待 API 调用完成
【发布时间】:2019-08-20 01:45:44
【问题描述】:

我是 Angular 新手,遇到了一个场景,我创建了两个组件 Student ComponentParent Component

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

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



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

这适用于学生组件。

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

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

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



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

当我为家长保存详细信息时,它应该保存新创建的学生和家长详细信息,并且还应该将新创建的学生链接到家长。

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

我用过:

@ViewChild(StudentDetail) studentDetail: StudentDetail;

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

在我的父组件类中

因此,如果我调试并检查它工作正常并且新学生链接到家长。 但有时当需要更多时间来保存学生数据时,它不会链接。我尝试使用:

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



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

【问题讨论】:

  • 我猜你需要在调用 SaveParent() 之前使用 await 关键字,比如: let result = await SaveParent();应该做的伎俩。其他方法是链接承诺以确保顺序
  • @HimanshuChaudhary 我尝试链接这两个承诺,但在某些情况下它也失败了,我将如何确保我的学生已成功保存到数据库并且我现在可以保存父详细信息。

标签: javascript angular typescript observable subscribe


【解决方案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..
   })

【讨论】:

    【解决方案2】:

    这里不需要 async 或 await 。你可以做这样的事情(简化一点,所以它可能需要一些工作):

    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$ 的主题并在 ngOnDestroy 中调用

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 2020-01-02
      • 1970-01-01
      • 2011-10-04
      • 1970-01-01
      • 2012-12-27
      相关资源
      最近更新 更多