JavaScript中信号的演变
#javascript #网络开发人员 #signals #reactivity

最近在“信号”一词中,前端世界中引起了一些嗡嗡声。在似乎很短的时间里,它们似乎无处不在,从PreactAngular

,但它们不是新事物。甚至没有遥不可及的话,如果您认为您可以在1960年代后期追溯到研究。在其基础上是相同的建模,它启用了第一个electronic spreadsheets和硬件说明语言(例如Verilog和VHDL)。

即使在JavaScript中,自声明性JavaScript框架的曙光以来,我们已经拥有了它们。随着时间的流逝,他们携带了各种名字,多年来出于流行。但是我们又来了,现在是一个很好的时机,就如何和原因提供更多背景。

免责声明:我是SolidJS的作者。本文从我的影响的角度反映了演变。 Elm SignalsEmber's computed propertiesMeteor都应该大喊大叫。

不确定什么是信号或它们的工作方式?查看此细粒反应性的简介:


在一开始的时候...

有时候发现多个政党大约在同一时间达到了类似的解决方案,这是令人惊讶的。声明性的JavaScript框架的开始,彼此之间有3次发行。

Angular的肮脏检查,骨干的模型驱动的重新租赁和淘汰赛的细粒度更新。每个都有些不同,但最终将作为我们今天如何管理状态和更新DOM的基础。

淘汰赛对本文的主题至关重要,因为它们的细粒度更新是基于我们呼叫信号的内容。他们最初介绍了两个概念observable(状态)和computed(副作用),但在接下来的几年中,将向前端的语言引入第三pureComputed(派生状态)。

const count = ko.observable(0);

const doubleCount = ko.pureComputed(() => count() * 2);

// logs whenever doubleCount updates
ko.computed(() => console.log(doubleCount()))

狂野西部

Image description

模式是从服务器上开发MVC和过去几年的JQUERY开发的模式的混合。一个特殊的常见被称为数据绑定,尽管以略有不同的方式,angular.js和nockout.js共享。

数据绑定是将一块状态附加到视图树的特定部分的想法。可以做的有力的事情之一就是使这个双向。因此,一个人可以更新DOM,然后DOM事件自动以一种简单的声明方式更新状态。

但是,滥用这种力量最终成为脚枪。但是不知道我们以这种方式构建了应用程序。在不了解什么变化的情况下,它会弄脏它会检查整棵树,并且向上传播可能会导致它发生多次。在淘汰赛中,这使得您很难遵循变化的道路,因为您要上下树木,并且周期非常普遍。

React出现了解决方案时,对我个人而言,正是Jing Chen的演讲巩固了它,我们已经准备好跳船了。


无故障

Image description

接下来的是大量采用反应。有些人仍然更喜欢反应性模型,并且由于对国家管理的反应不是很有可能,因此很可能两者都混合。

Mobservable(2015)是该解决方案。但是,除了与React合作之外,它给桌子带来了新的东西。它强调了一致性和无故障的传播。那就是,对于任何给定的更改,系统的每个部分都只能同步运行一次。

它是通过将其前身中的典型基于推动的反应性与推式混合动力系统进行交易来实现的。更改的通知被推出,但将派生状态的执行延迟到读取的位置。

Image description

为了更好地了解Mobservable的原始方法,请查看:Michel Westrate的Becoming Fully Reactive: An in Depth Explanation of Mobservable

尽管React将重新渲染读取的组件变化的事实在很大程度上掩盖了这个细节,但这是使这些系统变得可疑且一致的巨大一步。在接下来的几年中,随着算法变得更加精致,我们将看到more pull based semantics的趋势。


征服泄漏的观察者

Image description

细粒反应性是Gang of Four's Observer Pattern的变体。虽然同步的强大模式也有一个经典的问题。一个信号可以强烈参考其订户,因此,除非手动处理,否则长寿命的信号将保留所有订阅。

此簿记在涉及嵌套的情况下,尤其是在累积的情况下变得非常复杂。筑巢在处理分支逻辑和树时很常见,如您在构建UI视图时发现的。

鲜为人知的图书馆S.js(2013)将提供答案。 S独立于大多数其他解决方案而开发,并在数字电路上更直接地建模,在数字电路上,所有状态变化都在时钟周期中起作用。它称其为国家原始信号。虽然不是第一个使用该名称的人,但这是我们今天使用的术语。

更重要的是,它引入了反应性所有权的概念。所有者将收集所有儿童反应范围,并在所有者自行处理中管理其处置,或者是重新执行。反应图将开始包裹在根所有者中,然后每个节点将作为其后代的所有者。该所有者模式不仅对处置有用,而且是将提供商/消费者环境构建到反应图中的机制。


调度

Image description

Vue(2014)也为我们今天的位置做出了巨大贡献。除了与MOBX保持锁定状态以及优化一致性方面的进步外,Vue自开始以来就具有细粒度的反应性。

vue与反应分享了虚拟DOM的使用,但反应性是一流的,它首先与框架一起开发,作为内部机制,将其选项API驱动到过去几年中,是在过去的几年中。组成API(2020)。

vue通过安排工作何时完成工作,从而向前迈进了一步。默认情况下,带有VUE的所有更改都是收集的,但直到下一个MicroTask上运行效果队列之前,都不会处理。

但是,此计划也可以用于执行诸如keep-alive(无计算成本的屏幕图)和Suspense之类的事情。即使是concurrent rendering之类的东西,这种方法也是可能的,确实表明了如何获得两全其美的基于拉力和推动的方法。


汇编

在2019年,Svelte 3向所有人展示了我们可以使用编译器多少。实际上,它们完全汇总了反应性。这并非没有权衡,但是更有趣的是,Svelte向我们展示了编译器如何平滑人体工程学的缺点。这将继续是这里的趋势。

反应性语言:状态,衍生状态和效果;不仅为我们提供了描述同步系统(例如用户界面)所需的一切,而且可以分析。我们知道可以准确的变化和在哪里。可追溯性的潜力是深刻的:

如果我们知道编译时间,我们可以减少JavaScript。我们的代码加载可以更加自由。这是QwikMarko中的可重复性的基础。


信号进入未来

鉴于这项技术的年龄是多大的,可能会探索更多的东西可能令人惊讶。但这是因为它是建模解决方案而不是特定解决方案的一种方式。它提供的是一种描述状态同步的语言,独立于您执行的任何副作用。

当时似乎不足为奇,它会被Vue,lood,preatect,Qwik和Angular采用。我们已经看到,它在Rust上,leptos和Sycamore在Dom doesn't have to be slow上显示WASM。甚至被React考虑在引擎盖下使用:

也许这很合适,因为React的虚拟DOM始终只是实现细节。

信号和反应性语言似乎是事物融合的地方。但这并不是很明显的首次亮相JavaScript。也许这是因为JavaScript不是最好的语言。我甚至说我们在前端框架设计中感到很多痛苦是语言问题。

无论这一切结束时,这都是迄今为止的旅程。随着这么多人引起信号的关注,我迫不及待地想看看我们下一步的地方。