网站搜索

angular - 使用 RxJS 加载和丰富项目列表的示例


我想获取一个包含多个项目的数组,然后获取并向该数组中的每个项目添加额外的数据。

在已知 getItemsList 和 getRelatedObject 的实现的情况下,如何实现方法 getEnrichedItemsList?

interface RelatedObject = {}

interface Item = {
  id: string;
  relatedObjectId: string;
}

interface EnrichedItem = Item & {
  relatedObject: RelatedObject ;
}

interface apiService = {
  getItemsList: (query: string) => Observable<Item[]>; // implemented
  getRelatedObject: (relatedObjectId: string) => Observable<RelatedObject>; // implemented
  getEnrichedItemsList: (query: string) => Observable<EnrichedItem[]>; // HOW TO IMPLEMENT?
}

答案#1

像这样吗?

  getEnrichedItemsList(query: string): Observable<EnrichedItem []>{
    return this.getItemsList(query).pipe(
      mergeMap(items => from(items)),
      mergeMap(item => this.getRelatedObject(item.relatedObjectId).pipe(
        map(relatedObject => Object.assign(item,{relatedObject}))
      ))
    );
  }

完整示例:https://stackblitz.com/edit/rxjs-ahllnu

答案#2

使用 forkJoin 同时执行多个请求,并发出与输入数组顺序相同的项目数组。

getEnrichedItemsList(query: string): Observable<EnrichedItem[]> {
  return this.getItemsList(query).pipe(
    switchMap(items => forkJoin(items.map(item => this.enrichItem(item))))
  )
}

enrichItem(item: Item): Observable<EnrichedItem> {
  return this.getRelatedObject(item.relatedObjectId).pipe(
    map(relatedObject => ({ ...item, relatedObject } as EnrichedItem))
  )
}

这保证了最终丰富项的顺序与 this.getItemsList(query) 接收到的顺序相同,而使用 from 和 mergeMap 时可能并非如此。