RxJS mergeMap的行为不符合预期

时间:2019-04-24 15:47:33

标签: rxjs

我有这段RxJS代码

this.listItems$ = this.store.select(EntityState.relationshipItems).pipe(
  map(fn => fn(12)),
  mergeMap(items => items),
  map(this.toListItem),
  toArray<ListItem>(),
  tap(x => console.log(x))
);

我尝试使用mergeMap(items => items)将数组“展平”,然后将map的每个项目复制到另一个对象,然后将其转换回数组。

但是,流量甚至没有到达最后一个tap。我可以看到调用了toListItem函数,但是我不明白为什么它会在那里停止。


将其转换为

this.listItems$ = this.store.select(EntityState.relationshipItems).pipe(
  map(fn => fn(12)),
  map(items => items.map(this.toListItem)),
  tap(x => console.log(x))
);

使它起作用,但是我想了解为什么上面的那个不起作用。

1 个答案:

答案 0 :(得分:1)

这是因为this.store.select(...)是一个永远不会完成的主题(如果这样做的话,您只能选择一次没有意义的数据)。

但是,toArray从其源收集所有发射,并且在其源完成时将发射单个阵列。但是源是this.store.select(...),它永远不会完成,因此toArray永远不会发出任何东西。

因此,最简单的解决方法可能就是重组您的连锁店:

this.listItems$ = this.store.select(EntityState.relationshipItems).pipe(
  map(fn => fn(12)),
  mergeMap(items => from(items).pipe(
    map(this.toListItem),
    toArray<ListItem>(),
    tap(x => console.log(x))
  )),
);

现在源是from,它在迭代items之后完成,因此toArray将收到完整的通知并发出其内容。