3

我有一个从后端获取数据的 Angular 解析器。我有以下调用要执行:

GetProject(projectId): Observable<IProject>
GetSites(projectId): Observable<ISites[]>
GetPersons(siteId): Observable<IPerson[]>

我正在尝试使用 combineLatest 但不确定如何在我的场景中使用 RxJs。我希望在解决之前完成所有请求,但 GetPersons() 应该将 GetSites() 结果中第一项的 id 作为输入。这是怎么做到的?

4

3 回答 3

3

它看起来更像是你只想连接几个调用:

forkJoin([GetProject(projectId), GetSites(projectId)]).pipe(
  concatMap(([project, sites]) => {
    const siteId = /* whatever here */;
    return GetPersons(siteId);
  }),
).subscribe(...);

这还取决于您是想在观察者中接收所有响应还是仅接收最后一个响应。如果您想要所有响应,那么您需要链接GetPersonsmap附加前两个响应:

GetPersons(siteId).pipe(
  map(persons => [project, sites, persons]),
)
于 2019-10-01T11:34:08.253 回答
2

创建重播主题:

const sub = new ReplaySubject(3);

然后拨打您的电话

this.getProject(1).pipe(
  tap(project => sub.next(project)),
  switchMap(project => this.getSites(1)),
  tap(sites => sub.next(sites)),
  switchMap(sites => this.getPersons(sites[0].id)),
  tap(person => sub.next(person))
);

您的重播主题将包含作为第一个值的项目,作为第二个值的站点,作为第三个值的人。

您可以combineLatest使用带有BehaviorSubject.

const obs = new BehaviorSubject([]);
const add = val => obs.pipe(
  take(1),
  map(v => ([...v, val]))
).subscribe(v => obs.next(v));

this.getProject(1).pipe(
  tap(project => add(project)),
  switchMap(project => this.getSites(1)),
  tap(sites => add(sites)),
  switchMap(sites => this.getPersons(sites[0].id)),
  tap(person => add(person))
);

这一次,返回的值将是所有值的数组。

最后,您可以使用复杂的语法来连接它们,而无需使用主题。

this.getProject(1).pipe(
  switchMap(project => this.getSites(1).pipe(map(sites => ([project, sites])))),
  switchMap(([project, sites]) => this.getPersons(sites[0].id).pipe(map(person => ([project, sites, map])))),
);
于 2019-10-01T11:37:57.307 回答
0
this.project$ = this.myService.getProject(projectId);
this.sites$ = this.myService.getSites(projectId);
this.persons$ = this.sites$.pipe(
  switchMap(
    (sites: ISites[]) => merge(...sites.map((site: ISites) => this.myService.getPersons(site.id))),
  ),
); // that should result in Observable<IPerson[][]>, you likely need to flatten it
于 2019-10-01T12:08:13.357 回答