Как использовать await в Array.prototype.map для ожидания Rx JS Observables - PullRequest
1 голос
/ 11 июля 2020

Как я могу дождаться результата внутри функции карты, где getFooBar возвращает наблюдаемое?

Ex-код:

this.fooBarResponse.fooBars.map(async (x) => {
      x.fooBar = await this.fooBarService
        .getFooBar(x.fooBarId.toString())
        .toPromise();

      return x;
    });

foobar.service.ts

getFooBar(id: string): Observable<FooBar> {
    return this.fooBarsCollection.doc<FooBar>(id).valueChanges();
}

Ответы [ 2 ]

0 голосов
/ 11 июля 2020

Уменьшите свой массив fooBars до одного наблюдаемого, который switchMap от одного до следующего

const { of } = rxjs;
const { switchMap, delay } = rxjs.operators;

const fooBarResponse = {
  fooBars: [{ fooBarId: 1 }, { fooBarId: 2 }, { fooBarId: 3 }, { fooBarId: 4 }, { fooBarId: 5 }, { fooBarId: 6 } ,{ fooBarId: 7 } , { fooBarId: 8 }]
}

const fooBarService = {
  getFooBar: x => of(`emitted ${x}`).pipe(delay(500))
};

fooBarResponse.fooBars.reduce(
  (obs$, x) => obs$.pipe(
    switchMap(_ => {
      console.log(`Switching from foobar ${x.fooBarId}`);
      return fooBarService.getFooBar(x.fooBarId.toString());
    })
  ),
  of(null) // start with some random observable
).subscribe(finalEmit => {
  console.log(finalEmit);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.6.0/rxjs.umd.min.js"></script>
0 голосов
/ 11 июля 2020

Array#map синхронно. Вместо этого используйте for...of l oop.

for(const x of this.fooBarResponse.fooBars){
    x.fooBar = await this.fooBarService
        .getFooBar(x.fooBarId.toString())
        .pipe(take(1))
        .toPromise();
}
...