写点什么

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

Bruno Couriol

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

    阅读完需:约 7 分钟

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

AI 大模型超全落地场景&金融应用实践,8 月 16 - 19 日 FCon x AICon 大会联诀来袭、干货翻倍!

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:543211

评论

发布
暂无评论

阿里巴巴、华为教你如何把数据真正用起来 | DBT How

三少爷的见

华为 数据中台 数字化转型 数据运营 证券行业

【项目实战】创建一个github库上传本地项目

小明Java问道之路

git GitHub 项目实战 8月月更

多线程常见面试问答知识点

浅羽技术

线程 多线程 线程池 进程 8月月更

云原生(二十九) | Kubernetes篇之自建高可用k8s集群优化

Lansonli

云原生 k8s 8月月更

你必须要会uvloop!让Python asyncio异步编程性能直逼Go协程性能

HullQin

Go golang 后端 websocket 8月月更

【实践】高性能PHP应用容器workerman快速入门

迷彩

即时通讯 通讯协议 8月月更 workerman 高性能php

番外篇 of 《Mimir 源码阅读(三): 任意乱序数据的写入》

Grafana 爱好者

Mimir

什么是 Golang?[译]

宇宙之一粟

快速搭建 SpringCloud Alibaba Nacos 配置中心!

王磊

spring cloud alibaba

备受资本市场关注的Zebec,是如何运作的?

鳄鱼视界

Mimir 源码分析(二):效率爆棚的分片压缩

Grafana 爱好者

Mimir

leetcode 696. Count Binary Substrings 计数二进制子串(简单)

okokabcd

LeetCode 算法与数据结构

毕业总结

Geek_7a789a

架构实战营心得

阿拉阿拉幽幽

vue2 el-checkbox实现分组全选/反选/半选

Mr.Cactus

Element UI JavaScrip 分组全选

最全面的Zebec Protocol全景解读,一文读懂Web3基建设施

股市老人

设计电商秒杀系统

Geek_7a789a

Kubernetes 微服务接口设计原则

CTO技术共享

毕业设计 - 电商秒杀项目

阿拉阿拉幽幽

常见网络协议考察知识点

浅羽技术

https 网络协议 HTTP TCP/IP 8月月更

面试常见IO问答知识点

浅羽技术

io nio AIo bio 8月月更

Mimir 源码分析(三):任意时间范围乱序数据写入

Grafana 爱好者

Mimir

消息队列选型对比

CTO技术共享

架构师学习毕业总结

Pengfei

开源一夏 | 分治算法其实很有趣

宇宙之一粟

开源 分治法 8月月更

Spring避坑指南:Spring声明式事务@Transactional避坑

崔认知

Spring避坑指南 避坑指南 @Transactional避坑

备受资本市场关注的Zebec,是如何运作的?

BlockChain先知

Kubernetes深入学习之二:编译和部署镜像(api-server)

程序员欣宸

Kubernetes 8月月更

监控系统夜莺分布式部署方案

CTO技术共享

【JVM】HotspotJVM内存区域解析

小明Java问道之路

JVM JVM内存结构 JVM内存模型 8月月更 JVM内存区域

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