簡體   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