JavaScript中的函数式反应式编程是否会导致侦听器引用出现更大的问题?

JavaScript中的函数式反应式编程是否会导致侦听器引用出现更大的问题?,javascript,reactive-programming,rxjs,bacon.js,elm,Javascript,Reactive Programming,Rxjs,Bacon.js,Elm,在JavaScript中,经常使用观察者模式。有一件棘手的事情,那就是观察者的参考文献。它们需要清理。对于常规应用,我使用以下经验法则: 如果受试者的寿命短于(或等于)观察者,我可以做subject.on('event',…) 如果受试者的寿命比观察者长,我需要使用observer.listenTo(受试者,'event',…) 在第二种情况下,listenTo知道观察者的生命周期,当观察者死亡时,它会自动删除监听器 在现代SPA(单页应用程序)风格中,在任何时候只有部分应用程序处于活动状态

在JavaScript中,经常使用观察者模式。有一件棘手的事情,那就是观察者的参考文献。它们需要清理。对于常规应用,我使用以下经验法则:

  • 如果受试者的寿命短于(或等于)观察者,我可以做
    subject.on('event',…)
  • 如果受试者的寿命比观察者长,我需要使用
    observer.listenTo(受试者,'event',…)
在第二种情况下,
listenTo
知道观察者的生命周期,当观察者死亡时,它会自动删除监听器

在现代SPA(单页应用程序)风格中,在任何时候只有部分应用程序处于活动状态,这一点变得非常重要。如果您将其与web套接字结合起来,这对于事件流来说是一个完美的候选者,而且最有可能是长寿命的,那么这就变得更加重要了

有了FRP,像事件流这样的东西代表了随时间变化的值,我(不知道它)创建了很多监听器。每个
过滤器
映射
平面映射
都会创建一个新流,该流与前一个流绑定(可能使用侦听器)

在我看来,决定如何以及何时删除这些侦听器似乎相当棘手。我无法想象我是第一个想到这个问题的人,但我在互联网上找不到太多关于这个问题的信息

我见过其他语言中的一些框架使用弱引用。JavaScript没有弱引用的概念(WeakMap在这里不可用)。尽管如此,这似乎是个坏主意,因为垃圾收集何时发生还不清楚

  • 在当前的框架中如何解决这个问题
  • 框架是否与对象的生命周期相关联?如果是:如何

在RxJs中,默认情况下,每个
观察者将在原始事件源上有一个单独的侦听器。所以,如果你有

var s = $('#textInput').keyupAsObservable()
s.subscribe(subscriber1);
s.map(function() {}).subscribe(subscriber2);
您将有两个键控侦听器。您可以使用
.publish().refCount()
使
可观察
保持与其源的单一连接

在Bacon.js中,可观察对象始终保持与其源的单一连接

在这两个库中,与源的连接都是延迟创建的(当添加
观察者时),并且在删除(最后一个)观察者时自动删除。因此,您不必手动管理侦听器

但是,如果
主题
的寿命长于
观察者
,则必须确保观察者在其寿命结束时停止订阅,否则将导致泄漏。这两个库都没有任何“神奇”的管理方法,因为对于库来说,您的
观察者
只是一个函数

就我个人而言,我经常创建一个名为
death
Observable
或任何为观察者发出生命终结信号的东西,然后不是订阅
主题,而是订阅
主题。takeUntil(death)


关于Elm,我的理解是,您已经立即建立了整个活动网络,因此不存在泄漏的可能性<代码>观察员
不能在以后添加。

如果您认为这个问题应该结束,请添加评论。也许可以添加一个建议,使问题更加具体。或者是指向一个更适合这个问题的地方的指针。如果不清楚,请提问。我真的很想用玻璃钢。对不起,我不得不投票关闭。这个问题太开放了。@JK。你对改进这个问题有什么建议吗?这个问题有点宽泛,但实际上是个很好的问题。你得到的是一张赞成票,而不是我的接近票:-)我想知道是否有人可以用多个当前框架的信息回答这个问题。如果没有,您将如何在关于不同框架的不同答案中选择公认的答案……您对Elm的理解是正确的,因此您可以在最后一句话中更加自信。该语言只允许静态事件网络(在Elm中称为信号图),因此代码可以(并且)编译为JavaScript,在初始化时构建完整的网络,而不必处理订阅/取消订阅。
death
是一个有趣的概念。很高兴知道,您提到的框架中没有一个有助于生命周期的东西。