Angular 循环获取可观察数组数据并获取其中的另一个数据数组

Angular Loop on fetched observable array data and fetch another array of data in it

你好,我有一个 API 调用 getItems(),return 数据如下:

[
 {
   name: 'item1',
   materials: [
     1,
     2,
     3,
   ],
 },
 {
   name: 'item2',
   materials: [
     2,
     3,
     6,
   ],
 }
 ...
]

另一个 API 调用 getMaterial(id) return 一个 material 的数据,如下所示:

{
  name: 'mat1',
  img: '/img.jpg'
}

我想要实现的是使用 materials 数据获取所有项目数据。我设法获得了 material 的所有可观察到的调用,但我不知道之后要做什么。

这就是我到目前为止所做的:

public getAllItemsData(): Observable<any> {
  return getItems().pipe(
    map((list: items[]) => {
      return list.map(item => {
        const allMat = item.materials.map(m => getMaterial(m))

        return forkJoin(allMat).pipe(
          map(data => {
            return {
              ...item,
              materials: data
            }
          })
        )
      })
    }),
  );
}

但它不起作用。感谢您的帮助。

试试这个。 使用 switchMap, mergeMap, from, forkJoin

getItems()
  .pipe(
    switchMap((items) =>
        // for each items
      from(items).pipe(
       // merge map to run parallel for each items
        mergeMap(({ materials, ...item }) =>
        // wait to retrive all materials details of current item at mergeMap
        // after completing use map to map item with retrived materials 
          forkJoin(
            materials.map((m) => this.getMaterial(m))
          ).pipe(map((materialDetails) => ({ ...item, materials: materialDetails })))
        )
      )
    )
  )
  .subscribe((result) => {
    console.log(result);
  });

与上面非常相似,只是管道嵌套较少

interface Item {
    name: string;
    materials: number[];
}

interface MaterialData {
    name: string;
    img: string;
}

public getAllItemsData() {
    return getItems().pipe(
        switchMap((items: Item[]) => from(items)), // use 'from' to deal with one Item at a time
        mergeMap(({ materials, name }: Item) =>
            forkJoin(materials.map((mat) => getMaterial(mat))) // create array of observables using map, and pass into forkJoin 
                .pipe(
                    map((materials) => ({ name, materials })), // reconstruct object
                ),
        ),
        toArray(), // collect all emissions and output as an array
    );
};

我认为您只是缺少最后一个 merge/forkJoin 来订阅您创建的可观察对象数组。

public getAllItemsData(): Observable<any> {

  return getItems().pipe(

    map((list: items[]) => 
      list.map(item => 
        forkJoin(
          item.materials.map(m => getMaterial(m))
        ).pipe(
          map(materials => ({
            ...item,
            materials
          }))
        )
      )
    ),

    // Subscribe to the list created above
    mergeMap((list:Observable<any>[]) => forkJoin(list))

  );

}