【问题标题】:Split an Observable of list in two将一个 Observable 列表一分为二
【发布时间】:2021-07-13 12:42:05
【问题描述】:

我有一个可观察的:

const allItems$: Observable = getAllItems();

Items[] 类似于:[false, false, true, false]

我想要的是将 allItems 拆分为两个 Observable:`trueItems$ 和 falseItems$ 我目前正在做的是:

const allItems$: Observable<Items[]> = getAllItems();
const trueItems$ = allItems$.pipe(map(items => items.filter(item => !!item)));
const falseItems$ = allItems$.pipe(map(items => items.filter(item => !item)));

注意:我使用角度 | async 在视图中显示 observables。

它工作正常,但问题是 allItems observable 被调用了两次(如果我在 getAllItems() 函数中执行console.log('hello'),我将在控制台中有 2 个“hello”。

是否有可能做到更清洁并将“allItems$”一分为二,控制台中只有一个“hello”?

【问题讨论】:

  • 您所描述的似乎比看起来更棘手。如果您将日志放在getAllItems() 中并且您看到两个日志,那么问题不在于这里的 RxJS,因为 RxJS 将对allItems$ 进行两次订阅,但它不能为您调用getAllItems()。所以看起来这段代码在你的应用程序中确实被调用了两次。仅当您返回延迟的 Observable 并且 console.log 在其回调中时,它才会生成两个日志,但由于您没有提及它,我想您没有提及。
  • 我相信我有 2 个管道异步的事实就像有 2 个订阅导致双重日志记录。 @Philipp Meissner 给出的解决方案对我有用
  • 您确实有两个订阅,但函数 getAllItems() 仅被调用一次,因此如果您看到两条日志消息,则取决于返回的 Observable 的实现方式以及 console.log 的放置位置。

标签: javascript angular rxjs observable


【解决方案1】:

在我看来,最简单的解决方案是 share 的最后一次发射 allItems$,这样所有额外/迟到的订阅者都不会导致源再次重播,而是收到缓冲的响应。

const allItems$: Observable<Items[]> = getAllItems().pipe(shareReplay(1));

从这里开始,像以前一样使用它。

阅读shareReplay 及其行为here。 基本上,它共享源并将指定数量的排放重放给迟到/额外的订阅者。

【讨论】:

  • 像魅力一样工作。非常感谢!
  • 这是一个很好的答案,但仅供参考,使用 RxJS v7,shareReplay 预计将被弃用,取而代之的是带有配置的 share 运算符。有关更多信息,请参阅:medium.com/volosoft/whats-new-in-rxjs-7-a11cc564c6c0
  • 谢谢@DeborahK
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-21
  • 1970-01-01
  • 1970-01-01
  • 2017-10-01
  • 2021-10-04
相关资源
最近更新 更多