写点什么

新的 Signals 提案旨在将 JavaScript 中的响应式编程原语形式化

Bruno Couriol

  • 2024-07-09
    北京
  • 本文字数:2190 字

    阅读完需:约 7 分钟

大小:970.78K时长:05:31
新的 Signals 提案旨在将 JavaScript 中的响应式编程原语形式化

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)的函数,其中:


  • n 为响应式系统处理的第 n 个事件,

  • state_n 是处理第 n 个事件时响应式系统的状态。


许多用于实现用户界面的框架(如 Angular2、Vue、React 等)更倾向于使用回调过程或事件处理程序,它们作为事件的结果,直接执行相应的响应。决定要执行哪些操作动作(无论是输入验证、局部状态更新、错误处理还是数据获取)通常意味着需要访问和更新一些并不总是在作用域内的状态。因此,框架会包括一些状态管理、依赖注入或通信能力,以在需要时处理状态传递,并在允许和必要时更新状态。


近年来,一种越来越流行的替代方法是,在方便和可能的情况下,声明输入事件与状态块之间的关系(例如,按钮单击 ->增加°C)、状态块本身之间的关系(例如, °F=°C*9/5+32 )以及状态与响应之间的关系(例如,°C 变化 ->更新屏幕上的仪表颜色)。这些声明是一次性生成并永久生效的,从而消除了开发人员因更新变量依赖项而忘记更新变量本身的一系列缺陷。


因此,一些 UI 框架要求开发人员使用特定的原语和语法(Svelte 中的 $ ;Vue 中的 refreactivecomputed )来声明这些关系。除了不同的语法之外,这种框架还可能采用不同的方式来实现响应性,并且可能存在轻微的语义差异。诚然,该提案针对的是框架维护人员及其方法的互操作性:


与 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 翻译,未经许可禁止转载。

2024-07-09 10:543563

评论

发布
暂无评论
发现更多内容

StoneDB 团队成员与 MySQL 之父 Monty 会面,共话未来数据库形态

StoneDB

MySQL 国产数据库 HTAP StoneDB 10月月更

Flowable 设置任务处理人的四种方式

江南一点雨

Java springboot flowable JavaEE

vue的几个提效技巧

yyds2026

Vue

顶级理解!阿里这份Github星标63.7K的Redis高级笔记简直不要太细

程序知音

Java 数据库 redis 架构 后端技术

详解webpack构建优化

Geek_02d948

webpack

聊聊Vuex原理

yyds2026

Vue

Apache RocketMQ 5.0 在Stream场景的存储增强

阿里巴巴云原生

阿里云 云原生 Apache RocketMQ

强引用、软引用、弱引用、幻象引用的区别

zarmnosaj

10月月更

展示出你的创意,知识库搭建也可以这样玩!

Baklib

深度探讨react-hooks实现原理

xiaofeng

React

企业级MQTT物联网接入平台EMQX正式上线VMware Marketplace

EMQ映云科技

物联网 IoT emqx 10月月更 VMware Marketplace

KunlunBase功能体验范例

KunlunBase昆仑数据库

MySQL 数据库

企业如何低成本快速搭建团队知识库,实现企业知识管理?

Baklib

我奋斗了 18 年才和你坐在一起喝咖啡

宇宙之一粟

全彩LED显示屏在单位形象的作用

Dylan

LED显示屏 全彩LED显示屏 led显示屏厂家

【直播回顾】OpenHarmony知识赋能第八期:手把手教你实现涂鸦小游戏

OpenHarmony开发者

OpenHarmony

Containerization and Its Benefits - Defining and Exploring

Mahipal_Nehra

container Docker Swarm tools APP开发 web 容器

快手 RocketMQ 高性能实践

阿里巴巴云原生

阿里云 RocketMQ 云原生

放弃 SpringCloud Gateway!Apache APISIX 在「还呗」业务中的技术实践

API7.ai 技术团队

spring-cloud SpringCloud Gateway APISIX 网关 开源、

软件测试 | 测试开发 | 测试过程中遇到的那些奇葩bug

测吧(北京)科技有限公司

测试

解读Vue3模板编译优化

yyds2026

Vue

我对软件工程的理解

老张

软件工程 质量保障

MobPush Android常见问题

MobTech袤博科技

android

量化自动套利分红机器人系统开发(成熟技术)

开发微hkkf5566

5分钟带您了解DSL、以太网线缆和光纤之间的区别,值得收藏!

wljslmz

dsl 光纤 以太网 10月月更

NFTScan 是什么?

NFT Research

区块链 NFT 多链 数据基础设施

epoll的实现原理

C++后台开发

数据结构 后台开发 linux开发 epoll C++开发

RocketMQ Streams在云安全及 IoT 场景下的大规模最佳实践

阿里巴巴云原生

阿里云 云原生 Apache RocketMQ

Apache SeaTunnel(Incubating) 2.2.0-beta 版本发布!API 重构,连接器与引擎解偶

Apache SeaTunnel

数据同步 Seatunnel 版本发布 数据集成平台 新版本/特性发布

如何搭建知识库网页?

Baklib

如何制作企业在线产品手册?这里有一些简单的方法!

Baklib

新的 Signals 提案旨在将 JavaScript 中的响应式编程原语形式化_后端_InfoQ精选文章