繁体   English   中英

如何在执行下一行代码之前等待嵌套订阅中的 API 响应

[英]How to wait for API response in the nested subscription before executing next line of code

我有一个方法应该返回一个布尔值,问题是这是异步的,我想避免竞争条件..

所以我有一些方法,例如:

someMethod(data: any): boolean{
 let isOccupied = false;
 firstValueFrom(this.checkIfOccupied('102')).then(toilet=> isOccupied = toilet.name === data.name);
 this.someObject.isOccupied = isOccupied;
 return isOccupied;
}

因此,在我继续使用this.someObject...之前,我想等待then( )内部发生的事情

checkIfOccupied看起来像这样:

  checkIfOccupied(toiletName: string): Observable<Toilet> {
    return this.store$
      .select(selectAlarmsForToilet(toiletName))
      .pipe(
        filter(res => !!res),
        take(1),
        switchMap((alarms: AlarmsObject[]) => {
          alarms.forEach(alarm => {
            if (Object.keys(alarm)[0].includes('occupied')) {
              const toiletId  = this.getToiletIdFromAlarm(toiletName, alarm); <= this method only finds needed ID
              if (toiletId ) {
                return this.toiletService.getToiletForId(toiletId ); <= this is API call
              }
            }
          });
          return of({} as SomeObject);
        }));
  }

我试图使其异步,然后在someMethod中使用 await 但它不起作用。 可能我在代码中犯了一些错误(我不想让someMethod异步 - 甚至可能吗?)

你的想法非常接近。

考虑一下您所说的话,我将对其进行过渡:

“在我继续下一行之前,我想等待一些东西”

所以像这样改变你的代码:

async someMethod(data: any): Promise<boolean>{
 let isOccupied = false;
 data = await firstValueFrom(this.checkIfOccupied('102'));
 this.someObject.isOccupied = toilet.name === data.name;
 return toilet.name === data.name;
}

您在 switchMap 中使用 Arrays.prototype.forEach,它对异步一无所知。

为了跟上竞争条件,您可以使用 forkJoin 运算符,它等待数组中的 Observables 完成,例如:

someMethod(data: any): boolean {
    let isOccupied = false;
    firstValueFrom(this.checkIfOccupied('102')).then(toilet => isOccupied = 
       toilet.name === data.name);
    this.someObject.isOccupied = isOccupied;
    return isOccupied;
  }

  checkIfOccupied(toiletName: string): Observable<any> {
    return this.store$
      .select(selectAlarmsForToilet(toiletName))
      .pipe(
        filter(res => !!res),
        take(1),
        switchMap((alarms: AlarmsObject[]) => {
          return alarms.length ? forkJoin(alarms
          .filter(alarm => Object.keys(alarm)[0].includes('occupied'))
          .map((alarm: any) => this.getToiletIdFromAlarm(toiletName, alarm))
          .filter(toiletId => !!toiledId)
          .map((toiletId: any) => {
           return this.toiletService.getToiletForId(toiletId); // api call
            })) : of([]);
        }));
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM