ReactiveX被认为是反应式编程吗? [关闭]

问题描述 投票:17回答:2

来自ReactiveX introduction page

它有时被称为“功能反应式编程”,但这是用词不当。 ReactiveX可能是功能性的,它可能是反应性的,但“功能反应性编程”是一种不同的动物。一个主要的不同点是功能性反应式编程对随时间连续变化的值进行操作,而ReactiveX对随时间发射的离散值进行操作。

同时,从Wikipedia's Functional Reactive Programming page,ReactiveX列在“实现”部分:

实现[编辑]

  • cellx,超快速实现javascript的反应性
  • Elm,编译为HTML,CSS和JavaScript的FRP语言
  • Ruby中的Frappuccino FRP实现
  • Flapjax,JavaScript中的行为/事件FRP实现
  • Reactive.jl,Julia中的FRP实现
  • ReactiveX,多种语言的FRP实现,包括Java,JavaScript,Python,Swift等等
  • Haskell中的reactive-banana FRP实现
  • ReactiveCocoa FRP在Swift和Objective-C中实现
  • ReactiveKit FRP在纯Swift中实现
  • Haskell中的Reflex FRP实现
  • Scala(和Scala.js)中的Scala.Rx FRP实现
  • 在C#,C ++,Haskell(不推荐使用[12]),Java,> Rust和Scala中使用Sodium,FRP实现
  • Haskell中的Yampa FRP实现

我非常了解ReactiveX的作用,并对“反应式编程”和“功能反应式编程”进行了一些研究,但我仍然无法区分它们之间的关系。

事实上,我有点认为维基百科页面用词不当,或者错误地列出了“实现”部分中的示例,因为我知道cellxReactiveX(两者都列在示例中)是为了解决完全不同的问题而构建的。

reactive-programming frp reactivex
2个回答
18
投票

这里反应香蕉图书馆的作者。

功能反应式编程(FRP)和反应式编程(RP)之间的关键区别在于,前者具有明确定义的指称语义,通常从类型中获得

type Behavior a  ~=  Time -> a
type Event    a  ~=  [(Time, a)]

而后者没有明确定义的指称语义。特别是,我所知道的RX的所有实现都遇到了合并事件流是非确定性的问题:当流包含同时发生的事件时,有时一个事件在另一个事件之前合并,有时则相反。

此外,“FRP对随时间变化的值进行操作”的说法既微妙不正确,也不是关键区别:

  • 首先,这个陈述最可能的解析是“行为是连续函数Time -> a”,这不是真的:行为可以是不连续的,例如它们可以是阶梯函数。更确切的是,FRP中的Time通常被认为是一个实数,即一个连续的值。
  • 其次,完全可能在时间不连续的情况下使用FRP。这不是RP的关键区别,而是关于您对值的操作是否具有明确定义的指称语义。

6
投票

据我了解,从ReactiveX(又名RX)的角度来看,根本不可能在同一个“时间”发生两个事件。这些只是内部,按顺序按订阅顺序触发的回调。 RX没有“管理”时间。

通过纯粹的FRP程序员的眼睛,RX可以表现得相当疯狂。考虑以下RXJS代码:

const xs = Rx.Observable
    .interval(0)
  //.share();

xs.combineLatest(xs, (a,b) => [a,b])
    .filter(ab => ab[1] > ab[0])
    .take(1)
    .subscribe(ab => alert(ab));

在这里,xs是一个寒冷的可观察区间,可以尽快发射。由于xs.combineLatest(ys, f)总是首先订阅xs,然后是ys,你会期望xs.combineLatest(xs, (a,b) => [a,b])产生[0,0], [1,0], [1,1], [2,1], ...所以ab[1] > ab[0]应该总是假的。但是,在我的电脑上,如果我让这段代码保持运行一段时间,它会在某些时候结束it could take a while, try it yourself

那是因为xs是一个冷可观察的:每次订阅interval都会创建一个独立运行的周期性计时器。这些计时器可以并且在某些时候以不同的顺序触发(特别是在.NET等多线程环境中)

如果我们注释掉//share线,使xs变热,序列永远不会完成,因为[0,0], [1,0], [1,1], ... ,[i,i-1],[i,i]...现在确定性地生成了。这是因为hot observable共享一个订阅。在这种情况下,只创建一个计时器。

在真正的FRP系统中,这种行为将是确定性的。但是,如果您真的要连接到真实FRP系统中的不同硬件定时器,您也会获得与RX相同的行为,因为这些外部事件将以随机顺序触发,除非两个定时器完全同步

© www.soinside.com 2019 - 2024. All rights reserved.