功能反应式编程优于事件监听器

时间:2014-05-24 18:12:28

标签: javascript event-handling functional-programming frp bacon.js

我一直听到很多关于功能性反应式编程的知识,并决定查看重要的是什么。通过bacon.js文档,似乎主要区别在于,不是在组件上设置事件侦听器,而是在其上创建事件流,并将事件处理程序传递到流中。换句话说,我真正做的就是将事件处理程序从组件移动到事件流。是吗?如果是这样,这样做的最大好处是什么?

2 个答案:

答案 0 :(得分:12)

功能反应式编程(FRP)的关键点是语法属性:

  

值的动态行为在声明时间指定。

例如,考虑一个可以通过按下按钮来计数或减少计数器的计数器。在命令式的风格中,您可能会这样写:

counter := 0                               -- initial value
on buttonUp   = (counter := counter + 1)   -- change it later
on buttonDown = (counter := counter - 1)

首先,计数器以初始值声明。然后,在代码的后面部分中,您可以更改该值。现在,如果有人问你问题"在任何给定的时刻,counter的价值是什么?",你必须查看引用该名称的代码的所有部分{ {1}},因为它可以在哪里更改。

相反,在使用FRP样式代码时,可以通过查看代码中的一个位置来回答问题:声明counter的位置。例如,在Haskell中,您可以将计数器写为

counter

右侧包含了解counter :: Behavior Int counter = accumulate ($) 0 (fmap (+1) buttonUp `union` fmap (subtract 1) buttonDown) 在任何特定时刻的价值所需的所有信息。特别是,您看到它可以由counterbuttonUp以及进行更改。您不必筛选代码,寻找计数器可能发生变化的地方,不,只需查看其声明并从那里进行跟进即可。

这就是为什么FRP代码比基于事件的意大利面条代码更容易出错的原因。

另见一些初步documentation for my threepenny-gui library

答案 1 :(得分:7)

  是吗?

没有。这是关于拥有事件流。你仍然会在最后附加监听器以执行效果,但是在源和目的地之间你有一个非常强大的抽象。

  

这样做的最大好处是什么?

事件流确实有很多higher-order functions可以轻松处理它们,并且编写它们而不会写出所有容易出错的样板代码。

作为the docs put it非常好,培根

  

通过从命令转换为功能,将您的事件意大利面变成清洁声明性风水培根。这就像用formap等函数式编程概念替换嵌套的filter - 循环一样。停止处理单个事件并改为使用事件流。将您的数据与mergecombine [并使用]更重的武器[如] flatMapcombineTemplate结合起来。