你就是函数响应式编程(FRP)啊?!【附 RxJS 实战】
前言
什么是 FRP?
英文全称是:Functional Reactive Programming,翻译过来就是:函数响应式编程。
对于函数式编程,我们并不陌生,在 我的 JS 专栏 里面可以找到很多相关文章~~
这里不妨先对函数式编程特性做简要回顾:
函数是一等公民<sub>(意味着可以把函数赋值给变量或存储在数据结构中,也可以把函数作为其它函数的参数或者返回值)</sub>
高阶函数<sub>(接受函数作为参数或者返回一个函数的函数)</sub>
没有隐式输入、输出<sub>(输入通过函数入参传递,输出通过函数 return 进行返回)</sub>
值的不变性<sub>(指在程序状态改变时,不直接修改当前数据,而是创建并追踪一个新数据)</sub>
声明式编程风格,而不是命令式编程风格<sub>(关注“是什么”,而不是“做什么”)</sub>
用代码举个简单例子:
以上代码用于实现计算阶乘。指令式编程,像机器一条条命令一样思考问题,一条条指令告诉计算机该怎么去处理这个问题。
而在函数式编程里面,思想是利用数学方法来思考问题。阶乘的数学表达式是:f(n) = n*f(n - 1)
(n > 1)
,f(n) = 1
(n = 1)
,利用递归解决问题。这个过程中基本上没有状态量,只有表达式,也没有赋值语句。
OK,说到这里,对函数式编程有了一个大体的回顾,下面就介绍今天的主角 —— 函数响应式编程
正文
从名字上来看,就是多了 响应 二字,什么是“响应”?
各位一定不陌生!
简答来说就是:当数据发生变动时,会自动触发告知我们:它发生变化了~
Vue.js 底层不就是这种响应式吗?Vue2 通过 definedProperty 的 getter/setter 收集数据变化(依赖收集);
当我们在使用 vue 开发时,只要一有绑定的数据发生改变,相关的数据及画面也会跟着变动,而开发者不需要写关于“如何通知发生变化”的代码,只需要关注发生变化时要做什么事,这就是典型的 Reactive Programming(响应编程) 。
所以,可以大致猜到:函数响应式编程 = 函数式编程 + 响应编程
事实上,它也确实如此~
一图胜千言:
编程范式关系图(部分)
如图,在声明式编程里,有 2 大家族,分别是函数式编程和数据流编程;数据流编程衍生出响应式编程;而函数响应式编程继承了函数式编程和响应式编程(各自的优点);
响应式编程能在运行时改变事件源(随时间变化的数据输入)的绑定处理,但数据流编程的组织是一开始就确定了的。
事件流
函数响应式编程(FRP) 可以更加有效率地处理事件流,而无需管理状态。
举个栗子🌰
其中 a 实际代表 b 与 c 之和,如果 b 或 c 持续不断在被改变,如何触发 a 值也跟着变化呢?
也就是说,上述代码只是一种表达式,并没有指定 a 值的变化依赖 b 和 c 。
可以使用 Reactive 响应式思想将值的关系进行绑定:
b 和 c 可以看成是被观察者,而 a 作为观察者,随着时间推移,b 和 c 的值不断变化,这种变化将传导到 a;
函数响应式编程(FRP)所做的就是:遍历整个事情流集合,将导致 b 和 c 变化的事情回放,并获得 a 的结果;
【事件流】被称为【被观察者序列】(observable sequences),其实被观察者是一种 Monads。
说明:既然是一种 Monads,就意味着存在延迟计算,即只有当变量真正使用时才去计算,整个链式遍历的过程也是这样。更多
RxJS
在 JS 中,能体现 FRP 的第三方框架是 RxJS。借助 RxJS,我们可以感受函数响应式编程大致是怎样的:
在原生 JavaScript 中
在 RXJS 中:
RxJS 是一套由 Observable sequences 来组合 非同步行为 和 事件基础 程序的 JS 库;可以把 RxJS 理解为处理 非同步行为 的 Lodash。
拖拽实战
再演示一个实战栗子🌰:
实现一个简单的拖拽功能;
拖拽功能,可理解为:对 mousedown
, mousemove
, mouseup
等多个事件进行观察,并相应地改变小方块的位置。
首先分析一下,为了相应地移动小方块,我们需要知道的信息有:
1). 小方块被拖拽时的初始位置;
2). 小方块在被拖拽着移动时,需要移动到的新位置。
数据流如下:
问题解析为:在每一次 mousedown
和 mouseup
之间触发 mousemove
时,更新小方块的位置。
如果是用常见命令式风格 JS 原生写:
对比二者似乎不难发现:监听事件流的方式更符合对事物变化的通常理解,并且代码的组织方式也更清晰,还有扩展性也更高(有兴趣阅读:RxJS 实战篇(一)拖拽,对于拖拽功能还有更多升级操作);
小结
OK,通过本文,我们了解了函数式编程、响应式编程、函数响应式编程的基本概念、特点、以及相互之间的关系;也借助 RxJS 了解了函数响应式编程的代码实现;
后续还将带来更多关于 RxJS 的相关内容~
如果觉得还不错的话,不如点个👍吧 O(∩_∩)O
我是掘金安东尼,输出暴露输入,技术洞见生活,再会~~
版权声明: 本文为 InfoQ 作者【掘金安东尼】的原创文章。
原文链接:【http://xie.infoq.cn/article/5bd667aced0a0c26aa274ad4f】。文章转载请联系作者。
评论