包阅导读总结
1.
关键词:JavaScript、Signals 提案、响应式编程、框架维护、互操作性
2.
总结:JavaScript 语言新增 Signals 提案处于第一阶段,旨在为框架维护人员提供通用原语实现响应式编程模式,该提案反映众多框架作者意见,引发讨论,包含示例和相关实现,促进响应式应用开发。
3.
主要内容:
– JavaScript 语言将 Signals 提案列入候选特性列表
– 该提案旨在为框架维护人员提供通用原语以实现响应式编程模式
– 深度反映众多框架作者/维护者意见
– 响应式应用程序的本质需求
– 与外部系统交互的接口
– 计算对输入事件的响应
– 发送操作动作到外部系统
– 实现响应式编程的方式
– 函数式 UI 方法依赖纯函数
– 一些框架使用回调或事件处理程序
– 新兴替代方法是声明输入、状态和响应之间的关系
– Signals 提案的相关情况
– 针对框架维护人员及方法的互操作性
– 计划进行早期原型设计和集成
– 提供实现计数器的示例
– 包含自动依赖项跟踪等实现
– 在 Reddit 上引发讨论
– 涉及浏览器效率和内存效率
– 关于 ECMAScript 内容的两种观点
– 相关链接和声明
思维导图:
文章地址:https://mp.weixin.qq.com/s/0rDKd5rj46Jmh_NhoJkIKg
文章来源:mp.weixin.qq.com
作者:Bruno??Couriol
发布时间:2024/6/26 9:39
语言:中文
总字数:2081字
预计阅读时间:9分钟
评分:90分
标签:
以下为原文内容
本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com
JavaScript 语言最近将 Signals 提案(目前处于第一阶段)添加到了致力于改进该语言的候选特性列表中。Signals 提案旨在为框架维护人员提供通用原语,以实现响应式编程模式。该提案深度反映了 Angular、Bubble、 Ember、FAST、MobX、Preact、Qwik、RxJS、Solid、Starbeam、Svelte、Vue、Wiz 等的作者 / 维护者的意见。
响应式应用程序本质上需要:一个与外部系统交互的接口,用于接收输入事件和发送操作动作;计算对输入事件的响应;以及将相应的操作动作发送到匹配的外部系统(例如,屏幕显示、远程数据库)。对于函数式 UI 方法(例如 Elm),响应计算依赖于纯函数(称为响应式函数),例如这样(actions_n, state_n+1) = f(state_n, event_n)
的函数,其中:
许多用于实现用户界面的框架(如 Angular2、Vue、React 等)更倾向于使用回调过程或事件处理程序,它们作为事件的结果,直接执行相应的响应。决定要执行哪些操作动作(无论是输入验证、局部状态更新、错误处理还是数据获取)通常意味着需要访问和更新一些并不总是在作用域内的状态。因此,框架会包括一些状态管理、依赖注入或通信能力,以在需要时处理状态传递,并在允许和必要时更新状态。
近年来,一种越来越流行的替代方法是,在方便和可能的情况下,声明输入事件与状态块之间的关系(例如,按钮单击 ->增加°C)、状态块本身之间的关系(例如, °F=°C*9/5+32
)以及状态与响应之间的关系(例如,°C 变化 ->更新屏幕上的仪表颜色)。这些声明是一次性生成并永久生效的,从而消除了开发人员因更新变量依赖项而忘记更新变量本身的一系列缺陷。
因此,一些 UI 框架要求开发人员使用特定的原语和语法(Svelte 中的 $
;Vue 中的 ref
、 reactive
和 computed
)来声明这些关系。除了不同的语法之外,这种框架还可能采用不同的方式来实现响应性,并且可能存在轻微的语义差异。诚然,该提案针对的是框架维护人员及其方法的互操作性:
与 Promises/A+ 不同的是,我们并不是在试图为面向开发人员的通用表层 API 寻找解决方案,而是在解决底层信号图的精确核心语义。[,] 这里的信号 API 更适合在框架之上构建,通过公共的信号图和自动跟踪机制提供互操作性。 该提案的计划是在进入第一阶段之前进行重要的早期原型设计,包括集成到多个框架中。只有当信号在实践中适合用于多个框架,并且相比框架自身所提供的信号,它能提供真正的好处时,我们才会对标准化信号感兴趣。该提案提供了一个实现计数器的简单示例:
const counter = new Signal.State(0);
const isEven = new Signal.Computed(() => (counter.get() & 1) == 0);
const parity = new Signal.Computed(() => isEven.get() ? "even" : "odd");
// 基于其他信号原语,库或框架定义的 effect 函数
declare function effect(cb: () => void): (() => void);
effect(() => element.innerText = parity.get());
// 模拟外部更新来计数......
setInterval(() => counter.set(counter.get() + 1), 1000);
这个示例展示了声明独立的状态块( Signal.state
)、绑定到它们的依赖项的状态块( Signal.computed
)的语法,以及库维护人员如何利用信号原语将操作动作的执行与状态的更改联系起来( effect(…)
)。
该提案包含了一个具有自动依赖项跟踪、惰性计算和记忆化备忘的实现。自动依赖项跟踪为开发人员工提供了更好的工效学(与手动提供依赖项相比——参见 React 的 useMemo)。懒惰计算和记忆化备忘可以防止不必要且不合时宜的计算,从而改善了 API 的性能。
该提案在 Reddit 上引发了有趣的讨论,其中一位开发者反思道:
这里可能确实存在 https://xkcd.com/927/ 的情况。但我认为所有的大框架都应该参与标准的创建,这一点非常重要。因此,这是从一大堆能解决信号所解决问题的方法开始的,而最终只会采用一种方法(框架在此基础上构建满足其特定需求)。
[…] 在浏览器中,这意味着它可能会更高效、更具内存效率,即使只是微小的改进(在这种规模下,微小的改进也会产生显著的影响)。
对于 ECMAScript 中应该包含什么以及不应该包含什么,基本上有两种基础的观点。[一个阵营] 认为应该只添加 / 包含基本内容,开发人员应该重新发明自己的轮子(或者使用一些 JS 库)。另一个阵营则认为,JS 应该为常见问题提供 API,并欢迎这样的标准,而
Object.groupBy()
则优于 lodash……依赖关系更少,需要交付的代码更少,对于“好吧,与我熟悉的库相比,这个库是如何解决问题的?”带来的挫败感也更少。
欢迎感兴趣的读者在线阅读完整的提案。GitHub 存储库包含了大量的解释和代码示例,用于阐明提案的目标、语法和语义。
响应式编程通过提供抽象来表达时变值(time-varying values)并自动管理这些值之间的依赖关系,从而促进了事件驱动的响应式应用程序的开发。人们提出了许多跨各种语言(如 Haskell、Scheme、JavaScript、Java、.NET 等)的方法。响应式编程与 JavaScript 特别相关——JavaScript 是用于 Web 应用程序的原生浏览器语言之一。
Bruno Couriol 拥有电信理学硕士、数学理学士学位。他从 30 年前写了第一个程序开始至今还一直在编写软件。主要帮助企业和非营利组织开发满足用户需求的软件。
原文链接:
https://www.infoq.com/news/2024/06/javascript-signals-proposal/
声明:本文由 InfoQ 翻译,未经许可禁止转载。