Массив HTTP Obserables to Asyn c -Pipeable Observable - PullRequest
0 голосов
/ 20 января 2020

Я пытаюсь сделать серию XHR GET на основе результатов первоначального запроса. У меня есть массив наблюдаемых вторичных запросов, которые я хочу сделать, и я могу использовать Array.map для итерации по ним и последовательно подписываться для регистрации всех возвращаемых значений, но я не могу понять, как отформатировать их в сплюснутую наблюдаемую что я могу распечатать на экране, используя единственную подписку async трубы:

ngOnInit() {
  // initial request - returns data on a planet
  this.planet$ = this.starWarsService.getEntityById("planets", "1");
  this.residentData$ = this.planet$.pipe(
    map(planets =>
      planets.residents.map(planet =>
        // get character data for each resident, `split` just grabs the index to construct the URL
        this.starWarsService.getEntityById("people", planet.split("/")[5])
      )
    ),
    tap(results => {
      results.map(result => {
        result.subscribe(data => {
          // this prints resident/character data correctly
          console.log("data", data);
        });
      });
    })
  );
}

Как я могу развернуть этот массив наблюдаемых объектов во что-то, что можно распаковать с помощью одной async трубы?

StackBlitz

Ответы [ 3 ]

0 голосов
/ 20 января 2020

ты хочешь чего-нибудь подобного?

this.planet$=this.starWarsService.getEntityById("planets", "1").pipe(
  share()) //<--pipe(share()) is for only one call
this.residentData$ = this.planet$.pipe( 
  switchMap((planet:any)=>{
     //with each resident create an observable and use forkJoin
    return forkJoin(planet.residents.map(x=>
         this.starWarsService.getEntityById("people",x.split("/")[5])))
  }))
0 голосов
/ 20 января 2020

Похоже, что вы хотите застегнуть ваши наблюдаемые, затем flatMap их. Результатом будет Observable, где T - это тип возвращаемого значения ваших отдельных наблюдаемых.

Примерно так:

this.residentData$ = this.planet$.pipe(
  flatMap(planets => zip(...planets.residents.map(planet =>
      this.starWarsService.getEntityById("people", planet.split("/")[5])))
  ),
  tap(result => {
    console.log('result', result);
  }),
);
0 голосов
/ 20 января 2020

Если вы хотите использовать asyn c, ждите на наблюдении, вы должны дать от него обещание. Вы можете использовать метод toPromise () в вашей наблюдаемой. Это наблюдаемое будет преобразовано в обещание, поэтому вы можете использовать await на нем

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...