微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将MergeMap与SwitchMap结合使用可从NgRx商店生成结果

如何解决将MergeMap与SwitchMap结合使用可从NgRx商店生成结果

我有3个选择器:

  1. getUserInfo =>以获取详细信息(示例输出{acntId: 'A1'}
  2. getAllDepartments =>获取所有部门ID的列表(示例输出['d1','d2']
  3. getAllDeptManagers =>以获得每个部门ID的部门经理列表。

现在,我已编写以下代码

 this.store
        .select(getUserInfo)
        .pipe(
          switchMap((res) => this.store.select(getAllDepartments,{ account: res.acntId})),mergeMap(deptId => this.store.select(getDepartmentManagers,{departmentId: deptId }))
        )
        .subscribe((depts) => {
          console.log(depts);
        })
    );

据我了解,mergeMap接受数组并相应地调用function并展平返回的可观察数组。

每次调用选择器['d1','d2']时,我都会得到getAllDeptManagers。我期望的是d1,然后是d2,依此类推,然后像控制台的depts一口气获得所有响应。

请帮助

解决方法

mergeMap不会使内部Observable的输出变平。它只是在内部Observable发出时重新发出,仅此而已。因此,您似乎想在此处使用forkJoin

mergeMap(deptIds => forkJoin(
  deptIds.map(deptId => this.store.select(getDepartmentManagers,{
    departmentId: deptId
  }).pipe(take(1)))
)),

然后,观察者将收到deptIds的单个结果数组,因为forkJoin将等到所有内部可观察对象完成。

,

实现所需目标的最简单方法是将数组映射到流中。第一个switchMap取一个值并将其映射到流上。该流将发出一个数组,因此您只需要一个mergeMap。像这样:

this.store.select(getUserInfo).pipe(
  switchMap(res => this.store.select(getAllDepartments,{ account: res.acntId})),mergeMap(depIdArr => depIdArr),// <- The extra bit
  map(deptId => this.store.select(getDepartmentManagers,{departmentId: deptId })),// Really,your source observables should be competeing,// but if they don't take(1) should ensure that they do.
  mergeMap(depMan$ => depMan$.pipe(take(1))),toArray()
).subscribe(console.log);

那个me​​rgeMap看起来很有趣(额外的一点),但是如果您返回一个数组,它将转换为流。在语义上与mergeMap(depIdArr => from(depIdArr))相同,但性能更高。

如果将数组转换为流并将其转换回数组太多,则可以将这些步骤与zip()combineLatest()或在这种情况下最好的组合:{{1} }

forkJoin()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。