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

2024-01-11

在 JavaScript 中,观察者模式经常被使用。其中有一件棘手的事情,那就是主体保留观察者的参考资料。他们需要清理。对于常规应用程序,我使用以下经验法则:

  • 如果主体的寿命短于(或等于)观察者,我可以这样做subject.on('event', ...)
  • 如果主体的寿命比观察者长,我需要使用observer.listenTo(subject, 'event', ...)

在第二种情况下,listenTo知道观察者的生命周期,当观察者死亡时,它会自动删除监听者。

在现代 SPA(单页应用程序)风格中,任何时候只有应用程序的一部分处于活动状态,这一点变得非常重要。如果将其与网络套接字(它是事件流的完美候选者并且很可能长期存在)结合起来,这一点就变得更加重要。

使用 FRP,拥有类似代表随时间变化的值的事件流之类的东西,我(在不知情的情况下)创建了很多侦听器。每个filter, map and flatMap创建一个与前一个流绑定(可能使用侦听器)的新流。

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

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

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

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

var s = $('#textInput').keyupAsObservable()
s.subscribe(subscriber1);
s.map(function() {}).subscribe(subscriber2);

您将有两个 keyup 侦听器。您可以使用.publish().refCount()做一个Observable保持与其源的单一连接。

在 Bacon.js 中,Observables 始终保持与其源的单一连接。

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

然而,在这种情况下subject寿命比Observer,您必须确保观察者在其生命周期结束时停止其订阅,否则就会发生泄漏。两个图书馆都没有任何“神奇”的方式来管理这个问题,因为对于图书馆来说,你的Observer只是一个函数。

我个人经常创建一个Observable called death或任何表明观察者寿命结束的信号,然后而不是订阅subject我订阅subject.takeUntil(death).

对于Elm,我的理解是,你一次性建立了整个事件网络,所以不存在泄漏的可能性;Observers无法在后期添加。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 使用Javascript自动打开弹出新窗口[重复]

    这个问题在这里已经有答案了 如何使用Javascript加载页面时打开弹出新窗口 我希望 当网站加载时 它会自动打开弹出新窗口 我使用以下内容 不行 尝试这个
  • Javascript图像编辑插件

    在哪里可以找到 Javascript 或 jQuery 图像编辑器插件 用户可以单击图像进行编辑 并且该插件允许他们进行裁剪 调整大小 旋转 翻转等 Pixastic http pixastic com lib 不再活跃 和CamanJS
  • 节点异步循环 - 如何使该代码按顺序运行?

    我知道有几个关于此的帖子 但根据我发现的那些帖子 这应该可以正常工作 我想在循环中发出 http 请求 并且不希望循环迭代 直到触发请求回调 我正在使用异步库 如下所示 const async require async const req
  • 元素存在之前的html5音频绑定时间更新

    我试图从音频标签绑定 timeupdate 事件 该标签尚不存在 我习惯这样做 body on click selector function e 我用音频标签尝试了这个 body on timeupdate audioPlayerJS a
  • 使用ajax发送表单数据

    我想用 ajax 以表单形式发送所有输入 我有一个这样的表单
  • Webpack将js/css文件内容直接注入到index.html

    我有这样的代码
  • 如何从左向右滑动文本和图像并具有滑动效果[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 为什么人们将自己的自定义/用户函数添加到 jQuery 对象中? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我见过人们将自己的自定义 用户功能添加到jQuery目的 例如 myUserFunc function regular JS code 你为什么
  • Durandal SPA 与打字稿有关的问题

    我使用 TypeScript 1 8 将我的 durandal SPA 应用程序从 VS 2012 更新到 VS 2015 它将生成 JavaScript ECMA5 我解决了所有构建错误 但我无法修复一个名为 return 语句只能在函数
  • 当key未知时如何获取js对象中的属性值

    我有一个对象数组 a 81 25 p 81 25 81 26 p 81 26 我想循环遍历数组并获取值p在每个元素中 for var key in a console log a key outputs 81 25 Object How d
  • 如何使用 javascript 将我的域名字母大写?

    假设我的域名是www hello com 如何使用 jQuery JavaScript 使浏览器的 URL 栏看起来像 www HELLO com 您无法更改浏览器地址栏中显示的内容 这是一项基本的安全功能 您可以使您的域名全部大写 并将页
  • Nodejs 异步 Promise 队列

    我需要使用速率受限的 API 例如 我一秒钟只能进行 10 个 API 调用 因此我需要等待当前秒结束才能进行另一个 API 调用 为了实现这一目标 我想创建一个可以自行管理的异步队列 它的主要功能是让我向队列添加一个新的 Promise
  • React setState回调返回值

    我是 React 新手 我希望实现这种流程 set the state execute a function f an async one which returns a promise set the state again return
  • 如何创建显示/隐藏 Docusaurus 项目中所有详细标签状态的按钮?

    根据讨论here https stackoverflow com questions 58579048 how to add or remove the open attribute from all details tags in a r
  • Python 中的 Firebase 身份验证时出现 KeyError:“databaseURL”

    相信你做得很好 我是 firebase 的新手 正在尝试进行用户身份验证 我已经安装了pyrebase4并在firebase控制台上创建了一个项目 我还启用了使用 电子邮件和密码 登录并尝试连接我的应用程序 下面是我正在尝试的代码 impo
  • 数据表 - 从 AJAX 源过滤数据

    我有一个数据表 正在从 api 获取数据 现在我的状态是活动的 非活动的 如果标志是活动的 那么我需要在数据表中显示 否则我不应该显示过期的 这是我的fiddle https jsfiddle net lakshmipriya001 qLp
  • 分配函数后如何删除 onmouseout 事件?

    我有一个问题 我正在为 onmouseout 事件分配一个函数 但运行该事件后 我需要将其删除 将非常感谢您的帮助 这取决于你的代码 如果你用 d3 这样做 那么你可以说 在 onmouseout 事件函数中 element on mous
  • 使用 NodeJS 创建 YouTube 播放列表

    我正在尝试使用 NodeJS 服务器创建 YouTube 播放列表 我已按照 Oauth 的 NodeJS 快速入门说明进行操作 如以下链接所示 https github com youtube api samples blob maste
  • javascript 加壳器与压缩器

    我想知道加壳器与压缩器的区别 优点是什么 即您应该在网络应用程序中部署压缩版本还是压缩版本 示例代码 var layout NAVVISIBLE 1 Init function this Resize Dimensions function
  • 数组长度未定义[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我试图按如

随机推荐