RXJS - множественные наблюдаемые вызовы массива свойств - PullRequest
3 голосов
/ 22 марта 2019

Я новичок в rxjs, и у меня довольно простой случай, с которым я не могу разобраться в angular.

У меня http-вызов для получения группы, эта группа содержитсписок идентификаторов друзей, список идентификаторов жанров и идентификатор региона.

Чтобы получить объекты знакомых через идентификаторы приятелей, я должен вызвать вызов через APIмой сервис (который возвращает 1 друга с указанным идентификатором).

Чтобы получить объекты моего жанра, я могу получить их из своего магазина, то же самое для региона.

Проблема в том, что у меня не может бытьрешение, разработанное с помощью каналов.

this.buddyService.getGroup(groupId).pipe(
    mergeMap((group) => forkJoin(
          mergeMap(() => forkJoin(group.buddyIds.map((id) => this.buddyService.getBuddy(id)))), 
          mergeMap(() => forkJoin(group.genreIds.map((id) => this.store.select(GenreState.genre(id))))),
          switchMap(() => this.store.select(RegionState.region(group.regionId))))
    ), takeUntil(this.destroyed$)
).subscribe(([group, buddies, genres, region]) => {

});

Итак, первая таблица mergeMap будет заключаться в получении всех результатов вместе в 1 подписке, затем у меня будет 3 дополнительных вызова для получения друзей, жанров и региона.

Я бы хотел, чтобы подписались мой первоначальный ответ (группа) и результаты 3 подколлов в 1, очевидно, это решение не работает, и я не могу заставить работать что-то еще.

Любая помощь будет оценена, спасибо!

Ответы [ 2 ]

2 голосов
/ 22 марта 2019

Кажется, у вас слишком много внутренних mergeMap с. Попробуйте это

this.buddyService.getGroup(groupId).pipe(
  mergeMap((group) => forkJoin(
    of(group),
    forkJoin(...group.buddyIds.map((id) => this.buddyService.getBuddy(id))), 
    forkJoin(...group.genreIds.map((id) => this.store.select(GenreState.genre(id)))),
    this.store.select(RegionState.region(group.regionId)))
  ),
  takeUntil(this.destroyed$)
)
.subscribe(([group, buddies, genres, region]) => {});

Основная проблема заключалась в том, что вы объединили «конструирующие» методы, которые создают наблюдаемых (например, forkJoin), с операторами, которые работают с существующими наблюдаемыми (например, switchMap или mergeMap).

Проверьте разницу самостоятельно: switchMap против forkJoin

Я написал это без глубокого тестирования, поэтому оно может не сработать сразу:)

1 голос
/ 23 марта 2019

Эта версия немного более многословна, но ее проще рассуждать, поскольку она разделена на несколько частей. Хотя не проверял.

import {combineLatest} from 'rxjs';

...

  const group$ = this.buddyService.getGroup(groupId);
  const buddies$ = group$.pipe(mergeMap(group => combineLatest(group.buddyIds.map((id) => this.buddyService.getBuddy(id))));
  const genres$ = group$.pipe(mergeMap(group => combineLatest(group.genreIds.map((id) => this.store.select(GenreState.genre(id))));
  const region$ = group$.pipe(switchMap(group => this.store.select(RegionState.region(group.regionId)))));

  combineLatest([group$, buddies$, genres$, region$])
    .pipe(takeUntil(this.destroyed$))
    .subscribe(([group, buddies, genres, region]) => {});
...