首页 > 解决方案 > 带有 rxjs 的内部订阅数组

问题描述

我正在尝试改进扁平化并减少我的 Rxjs 代码中的链接。

我的服务getAllItems()的 REST 调用返回以下 Items[]:

[{
  id: 101,
  name: 'Car',
  owner: 1
},
{
  id: 102,
  name: 'Table',
  owner: 2
}]

我有另一个端点getOwnerInfo(id:number)它提供基于“所有者”ID的信息,我想要组合的信息,所以最终答案应该如下所示:

[{
  id: 101,
  name: 'Car',
  owner: {
    id: 1,
    username: 'Mikelinin',
    name: 'Mikel',
  },
},
{
  id: 102,
  name: 'Table',
  owner: {
    id: 2,
    username: 'Thominin',
    name: 'Thomas',
  },
}]

我当前的实现 .subscribe 一次调用getAllItems,然后在订阅正文中迭代每个订阅getOwnerInfo的元素。

我一直在查看其他扁平化示例,但基本上它们“破坏”了数组,并且他们从未将其重新组合在一起。我需要输出是一个数组。

我尝试使用from()concatMap()mergeMap()但似乎我无法正确组合这两个请求。

标签: javascriptrxjsswitchmapmergemap

解决方案


下面将使用from将不同的所有者 ID 数组转换为所有者 ID 流。然后它将使用toArray将该流转换回一个数组,并将项目数组映射到具有各自所有者对象的项目数组。

this.getAllItems().pipe(
  switchMap(items => {
    const ownerIds = Array.from(new Set(items.map(x => x.owner)));
    return from(ownerIds).pipe(
      concatMap(x => this.getOwnerInfo(x))
      toArray(),
      map(owners => items.map(x => ({ ...x, owner: owners.find(y => y.id === x.owner) })))
    )
  })
)

推荐阅读