反应式编程

科技工作者之家 2020-11-17

反应式编程(Reactive programming,Rx)最初来源于函数式语言里面的函数式反应编程(Functional Reactive programming,FRP)。后来随着微软.Net Framework增加了Reactive Extension而在主流语言中流行起来。

创建反应式编程语言的方法在创建反应式编程语言时采用了几种流行的方法。特定于各种域约束的专用语言的规范。这些约束通常以实时,嵌入式计算或硬件描述为特征。另一种方法涉及通用语言的规范,其包括对反应性的支持。其他方法在定义中使用,并且使用编程库或嵌入式域特定语言,这些语言能够在编程语言的旁边或之上实现反应。规范和这些不同方法的使用导致语言能力权衡。通常,语言越受限制,其关联的编译器和分析工具能够通知开发者越多(例如,在执行分析程序是否能够实际实时执行时)。特异性的功能性交易可能导致语言普遍适用性的恶化。

编程模型和语义各种模型和语义决定了反应式编程的范畴。 我们可以沿着以下维度松散地拆分它们:

Synchrony:是时间同步与异步的基础模型吗?

决定论:评估过程和结果中的确定性与非确定性。

更新过程:回调与数据流与参与者。

实施技术和挑战实施的本质反应式编程语言运行时由图表表示,该图标识所涉及的反应值之间的依赖性。在这样的图中,节点表示计算和边缘模型依赖关系的行为。这样的运行时使用所述图形来帮助它跟踪各种计算,一旦所涉及的输入改变值,这些计算必须重新执行。

改变传播算法各种抽象实现方法使得能够规范反应式编程。使用这样的图表明确地描述了数据流。最常见的算法是:拉、推、混合推拉式。

什么推在实施层面,事件反应包括跨图表信息的传播,该信息表征变化的存在。因此,受此类更改影响的计算将变得过时,并且必须标记为重新执行。然后,这种计算通常以其相关源的变化的传递闭包为特征。然后,更改传播可能会导致图形接收器值的更新。

图传播信息可以包括节点的完整状态,即所涉及节点的计算结果。在这种情况下,将忽略节点的先前输出。另一种方法涉及增量传播,即增量变化传播。在这种情况下,信息沿着图形边缘激增,图形边缘仅包括描述前一个节点如何变化的增量。当节点保存大量状态数据时,这种方法尤为重要,否则从头开始重新计算会很昂贵。

Delta传播本质上是一种优化,已经通过增量计算学科进行了广泛的研究,增量计算的方法需要运行时满意度,包括视图更新问题。这个问题的臭名昭着是使用数据库实体,它们负责维护不断变化的数据视图。

另一个常见的优化是采用一元变化积累和批量传播。这种解决方案可以更快,因为它减少了涉及的节点之间的通信。然后可以采用优化策略来推断其中包含的变化的性质,并相应地进行改变。例如批处理中的两个更改可以相互抵消,因此,只需忽略。另一种可用的方法被描述为无效通知传播。此方法导致具有无效输入的节点拉取更新,从而导致更新其自己的输出1。

构建依赖关系图有两种主要方法:

依赖关系图在事件循环中隐式维护。注册显式回调,然后导致创建隐式依赖。因此,通过回调引起的控制反转因此留在原地。然而,使回调起作用(即返回状态值而不是单位值)需要这样的回调变为组合。

依赖关系图是程序特定的,由程序员生成。这有助于以两种方式寻址回调的控制反转:显式指定图形(通常使用可嵌入的特定于域的语言(DSL)),或者使用有效的表达和生成隐式定义图形,原型语言。

途径运行可以将反应式编程与普通的命令式编程融合在一起。在这样的范例中,命令式程序在反应式数据结构上运行。这种设置类似于约束命令式编程; 然而,当约束命令式编程管理双向约束时,反应式命令式编程管理单向数据流约束。

面向对象面向对象的反应式编程(OORP)是面向对象编程和反应式编程的组合。 也许进行这种组合的最自然的方法如下:对象不是方法和领域,而是当他们所依赖的其他反应被修改时,对象会自动重新评估。

下面是使用JavaScript和jQuery的A = X + Y介绍示例的说明:

X: Y: A: function setA() { // A=X+Y as integers var A = parseInt($('#X').val()) + parseInt($('#Y').val()); $('#A').text(A);}setA(); // for initial value of A$('#X,#Y').css('cursor', 'pointer').click(function () { // by reaction to a click at X or at Y... var obj = $(this); obj.val(parseInt(obj.val()) + 1); // updates X or Y setA(); // updates A});如果OORP编程语言保持其命令性方法,那么它也属于命令式反应式编程的范畴。

本词条内容贡献者为:

王沛 - 副教授、副研究员 - 中国科学院工程热物理研究所

科技工作者之家

科技工作者之家APP是专注科技人才,知识分享与人才交流的服务平台。