Functional programming RxJs操作符groupBy是否可以泄漏内存?

Functional programming RxJs操作符groupBy是否可以泄漏内存?,functional-programming,rxjs,reactive-programming,Functional Programming,Rxjs,Reactive Programming,我试图对RxJs操作符groupBy的用例进行分析,我担心在某些情况下可能会导致内存泄漏 我熟悉传统意义上的groupBy(例如同步列表处理)。我将写出一个groupBy函数来引用: const groupBy = f => list => list.reduce((grouped, item) => { const category = f(item); if (!(category in grouped)) { grouped[categor

我试图对RxJs操作符
groupBy
的用例进行分析,我担心在某些情况下可能会导致内存泄漏

我熟悉传统意义上的groupBy(例如同步列表处理)。我将写出一个groupBy函数来引用:

const groupBy = f => list =>
  list.reduce((grouped, item) => {
    const category = f(item);
    if (!(category in grouped)) {
      grouped[category] = [];
    }
    grouped[category].push(item);
    return grouped;
  }, {});

const oddsAndEvens = x => x % 2 === 0 ? 'EVEN' : 'ODD';

compose(
  console.log,
  groupBy(oddsAndEvens)
)([1,2,3,4,5,6,7,8])

// returns: { ODD: [ 1, 3, 5, 7 ], EVEN: [ 2, 4, 6, 8 ] }
请注意,这在更广泛的范围内是无状态的。我假设RxJs做了类似的事情,在偶数和奇数的地方会有返回的可观测值,并且它会有状态地跟踪行为类似于集合的组。如果我错了,请纠正我,主要的一点是,我认为RxJs必须维护所有分组的状态列表

我的问题是,如果分组值的数量(本例中仅为偶数和奇数)不是有限的,会发生什么?例如,为您提供唯一标识符以在流的生命周期内保持一致性的流。如果您按此标识符分组,RxJs的groupBy操作符是否会继续创建越来越多的组,即使旧标识符永远不会被再次访问

我的问题是,如果分组值的数量(本例中仅为偶数和奇数)不是有限的,会发生什么

这只能在无限流中发生(因为在源流中,组的数目不能超过值)。答案很简单:您将不断创建新的可观察对象

每个
GroupedObservable
的寿命与源代码一样长(源代码完成时,组完成),如您所见:

从技术上讲,这里没有内存泄漏,因为您正在积极地观察一个无限的可观察对象。一旦源observable完成,所有组也将完成:

source$
  .takeUntil(stop$)
  .groupBy(…)
但从技术上讲,将一个无限的可观察对象分组到一个唯一的属性上,而不取消订阅源不会对您的内存使用产生很大的帮助,不会

如果您按此标识符分组,RxJs的groupBy操作符是否会继续创建越来越多的组,即使旧标识符永远不会被再次访问


这里要指出的是rxjs对此无能为力。它无法知道一个组是否完成,或者它是否会在以后的某个时间接收到另一个值。

如果您的流是无限的,并且您的键选择器可以生成无限的组,那么-是的,您有内存泄漏

您可以为每个分组的可观察对象设置持续时间选择器。为每个组创建持续时间选择器,并在组过期时发出信号

rxjs 5+:groupBy第三个参数

rxjs 4:改用GroupedByTill操作符

这里是一个无限流的例子,其中每个分组的观测值在3秒后关闭

Rx.可观测间隔(200)
.群比(
x=>数学楼层(x/10),
x=>x,
x$=>Rx.Observable.timer(3000).finally(()=>console.log(`closing group${x$.key}'))
)
.mergeMap(x$=>x$.map(x=>`group${x$.key}:${x}`)
.subscribe(console.log)

我认为这并不是特定于
groupBy
的。无限列表上所有累积结果的操作都有可能在某个时刻耗尽内存。