响应式编程简称RP(Reactive Programming),是一种面向异步(asynchronous)数据流(Data Stream)的编程范式。其实,这并不是什么新东西,而是新瓶装旧酒,把编程中常用的发布-订阅模式发扬光大,然后形成一整套可供我们高效解决问题的编程范式。
接上面说的,其实数据流也不是新东西。举个例子,我们在浏览器中单击一个按钮,这个点击事件(event)就是一个真正的异步数据流(asynchronous data stream),以下简称流。在这个流里面,你可以观察一些对象,也可以做一些响应处理,总之随你喜好。
而且,我们可以把任意东西包装成流,而不限于点击事件、或者鼠标滑过事件。流无处不在,信手拈来,任意东西都可以成为流:变量、用户的操作、属性、缓存、数据结构等等。譬如:假想你的微博首页是一个流,那么你就可以监听它的变化,并且根据需要采取阅读与否的决定(做出响应)。
最重要的是,我们将获得令人惊叹的功能工具箱,这个工具箱里面有一系列函数,可以帮助我们组合、创建、过滤这些流。是的,这时候函数式编程就派上用场了。如果不了解函数式编程,可以看本书之前的相关章节。
流可以用作另一流的输入, 甚至多个流也可以用作另一个流的输入。 您可以合并两个流。 您可以过滤流以获得另一个只包含您感兴趣的事件的流。您可以将数据值从一个流映射到另一个新流。
既然流对于响应式(Reactive)如此重要,那么,让我们从熟悉的“单击按钮”这个事件流开始细致地研究它们。接下来我们看一个图,因为看起来像一颗颗弹珠,通常这类型的图叫弹珠图。
如上图,水平从左至右的箭头线表示时间线。流是按时间顺序排列的一系列进行中的事件, 它可以含有三种不同的东西:
- 一个值(是某种类型的)。也就是上图的各色弹珠。
- 一个错误(也可能没有)。也就是上图的红叉。
- 一个“完成”信号(也可能没有)。也就是上图中时间线上的竖线。 例如,当包含该按钮的当前窗口或视图关闭时,可以认为流发出了“完成”信号。
接下来,让我们做点有趣的事情:创建从原始点击事件流转换而来的新点击事件流。
在函数式编程我们介绍过带有map方法的函子(比如Array就是函子,实现了map方法)。map方法接受一个函数,让该函数处理函子里面的数据,输出另一个函子。这段说得比较学术化,但其实说白了,就是将原数据通过map转换一下,得到一个新的数据,如此而已。
针对流,我们也可以类似的这么做。输入一个流,通过map(等)函数处理一下,变成一个新的流。
//todo
上面介绍了一些响应式编程的技术特征,那么响应式编程的必要性是什么呢?可以先简单讲一下。后面再以实例展开叙述。
响应式编程提升了代码的抽象层次,让我们可以专注于处理业务逻辑,而不必关注太多细枝末节的事情:比如服务器端数据变化后,前端变量值的实时获取、及时更新其他有关的变量、以及界面的再次渲染。使用响应式编程会让这些细碎的事情变得更简单。
在与大量数据事件相关的、UI事件高度交互的现代Web应用程序和移动应用程序中,响应式编程的好处更加明显。10年前,与网页的交互基本上是向后端提交一个form表单,后端处理好之后,再向前端执行“粗暴的”渲染逻辑以呈现变化。现代的应用程序已经变得更加实时:修改单个表单字段可以自动触发到后端的保存,对某些内容的“点赞”可以实时反映给其他已连接的用户……等等。
如今,现代应用程序具有各种实时事件,可以为用户带来高度交互的体验。我们需要适当处理这些问题的工具,而响应式编程就是一个不错的选项。
{% hint style="info" %} https://gist.github.com/staltz/868e7e9bc2a7b8c1f754 {% endhint %}