Javascript Rx.Observable.groupBy会清理空流吗?
在节点应用程序中,我尝试使用RxJS处理事件流。事件流是许多文档的更改列表。我使用groupBy按documentId将流划分为新的流。但我想知道,一旦客户机上关闭了一个文档,并且该文档ID的流中没有添加新事件,groupBy会在该文档的流为空时处理它吗?如果没有,我将如何手动执行该操作?我想避免新文档流被创建但从未被销毁而导致内存泄漏。既然您包含了.NET标记,我也将介绍Rx.NET 你的问题措辞有点不正确。流是空的当且仅当它们从未有事件时。所以,它们不能变成空的。但是,不发送数据的流通常不会消耗太多资源 在.NET中,在源终止之前,组不会终止。我们使用“GroupByTill”,它允许您为每个组指定一个durationSelector流。可观察的。计时器通常对此很有效 这意味着,随着时间的推移,可能会出现多个具有相同密钥的非并发流,但如果(通常情况下)您的组流在某个点被展平,则这无关紧要 在rxjs中,我们还有GroupByTill 在RXJava中,行为类似的groupByTill方法被滚动到groupBy中—有关更多详细信息,请参见和 说: 如果您取消订阅其中一个GroupedObservable,该GroupedObservable将被终止。如果源Observable随后发出一个项,其键与以这种方式终止的GroupedObservable匹配,groupBy将创建并发出一个新的GroupedObservable以匹配键 因此,在RXJava中,您必须从分组的可观察流中取消订阅以终止它Javascript Rx.Observable.groupBy会清理空流吗?,javascript,system.reactive,reactive-programming,rx-java,reactive-extensions-js,Javascript,System.reactive,Reactive Programming,Rx Java,Reactive Extensions Js,在节点应用程序中,我尝试使用RxJS处理事件流。事件流是许多文档的更改列表。我使用groupBy按documentId将流划分为新的流。但我想知道,一旦客户机上关闭了一个文档,并且该文档ID的流中没有添加新事件,groupBy会在该文档的流为空时处理它吗?如果没有,我将如何手动执行该操作?我想避免新文档流被创建但从未被销毁而导致内存泄漏。既然您包含了.NET标记,我也将介绍Rx.NET 你的问题措辞有点不正确。流是空的当且仅当它们从未有事件时。所以,它们不能变成空的。但是,不发送数据的流通常不会
takeUntil
和计时器
流可用于此
增编:
作为对您评论的回应,在下游运营商取消订阅之前,流不会终止。groupByUntil的持续时间选择器将导致终止。如果文档关闭后不会再次打开,那么您可以将“documentclosed”事件发送到流中,并在测试“documentclosed”时使用带有takeWhile的常规groupBy
之所以不再次打开文档很重要,是因为使用groupBy(在rx js和rx.net中),如果已经看到的密钥重新出现,则不会创建新的组
如果这是一个问题,那么您需要使用groupByUntil并使用已发布的流来监视documentClosed事件-使用已发布的流将确保您不会收到订阅的副作用。我建议您执行以下操作: 与其让documentChanges可见,不如让documentEvents可见 客户端在打开文档时发送DocumentOpen事件,在更改文档时发送documentChanged事件,在关闭文档时发送documentClosed事件 通过通过相同的可观察对象发送所有3种类型的事件,可以建立并保证有序性。如果一个客户端以该顺序发送DocumentOpen、documentChanged、documentClosed事件,那么您的服务器将以该顺序看到它们。注意:对于两个不同的客户端发送的事件顺序没有任何保证。这只会让您确保特定客户端发送的事件是有序的 然后,这就是如何使用
groupByUntil
:
documentEvents
.groupByUntil(
function (e) { return e.documentId; }, // key
null, // element
function (group) { // duration selector
var documentId = group.key;
return group.filter(function (e) { return e.eventType === 'documentClosed'; });
})
.flatMap(function (eventsForDocument) {
var documentId = eventsForDocument.key;
return eventsForDocument.whatever(...);
})
.subscribe(...);
另一个简单得多的选项是:您可以在空闲时间后使组过期。根据您对事件的处理情况,这可能已经足够了。如果文档在5分钟内未被编辑,此示例将使组过期。如果有更多的编辑进来,那么就会有一个新的组
var idleTime = 5 * 60 * 1000;
events
.groupByUntil(
function(e) { return e.documentId; },
null,
function(g) { return g.debounce(idleTime); })
.flatMap...
OP正在使用
RxJs
(节点)。他错误地标记了他的问题:)我真的是指你的RXJava建议,这对RxJs没有帮助,因为RxJs和Rx一样工作。NET@James谢谢如果流在事件仍然是进程时终止,它们会结束吗?我所处的场景是,我需要按顺序处理文档。这是至关重要的。如果流在处理所有事件之前终止,则会导致问题。抱歉,标记错误。由于Rx可用于多个平台,我认为这些概念将适用于大多数/所有Rx实现。您最终需要让客户端发出一个文档关闭事件。然后,您可以使用James描述的groupByUntil
,并提供由文档id过滤的文档关闭事件流作为durationSelector
子句。谢谢,Brandon。我想听听你对我关于在流上的事件仍在处理时终止流的评论的看法。