RX的前世今生
源自微软,火于NetFlix公司。2011年微软开发出RX框架(开发的LinQ扩展出来的开源方案),由于当时的netFlix公司发展太快,旧有的一些架构问题加上新增长的一些问题,导致架构特别复杂,一直在寻找一套能够梳理清楚这种复杂架构的框架或模式。NetFlix公司借鉴了RX的设计理念,基于JAVA语言开发出了RxJava。从此RX框架迎来了爆发点。发展至今,RX已经形成了一个开源集合,支持多种语言。
LinQ 读作Link,全名是 Language-Integrated Quey,其功能很多元、强大,学习Rxjs可以不用会,当然如果你感兴趣,可以去探索!
支持的语言:reactivex.io/languages.h…
RX 是 Reactive Extension缩写
RX的优势?
通过流的抽象,解决了很多现实场景问题
擅长处理异步操作
复杂问题分解成一个个单体,通过组合各个单体解决复杂问题
在实际应用中,很多问题可以抽象成数据流,网页的DOM事件、Ajax获取数据资源等操作都可以看成(抽象)是一个数据流。
RxJS擅长处理异步操作,因为它对数据是采用推的处理方式。当一个数据产生的时候,会被推送给对应的处理函数,这个处理函数不用关心数据是同步产生的还是异步产生的,异步与同步做到了有机统一,实现了同一套API处理异步、同步数据流。
Rxjs中的数据流可能包含复杂的功能,但是可以分解成一个个单体来实现,实现某个小功能就是操作符,学习RxJS就是学习如何组合操作符来解决复杂问题。
Know Rxjs
Rxjs是一套由Observable sequences 来组合异步行为和事件流的library
简单的说,可以把Rxjs看成是异步的lodash或Underscore
同时这也被为Functional Reactive Programming,更确切的说是指Function Programming和Reactive Programming两个编思想的结合
Rxjs 确实是Functional Programming 跟Reactive Programming的结合,但能不能称为Functional Reactive Programming(FRP)一直存在争议
Rx在官网上特别指出,有时被称为FRP其实是个误称
简单的说FRP是操作随着时间连续性改变的数值而Rx则比较像操作随者时间发出的离散数值(这个部分不用分得太细,因为社区对FRP的定义及解释一直存在争议....)
本次训练营偏向称Rx为FRP,(FP+RP=FRP)比较直观,易理解!
Async FAQ(异步常见问题)
- Race Condition 竟态条件
- Memory Leak 内存溢出
- Complex State 复杂的状态
- Exception Handling 异常处理
Race Condition
每当我们对同一个资源同时做多次的非同步存取时,就可能发生 Race Condition 的问题。比如说我们有一个文章列表,让我们从第一个选中的文章标题开始。然后选中第二个文章标题。该应用发送一个请求去加载文章,由于网络原因,文章内容加载需要一小会儿。数秒之后,用户厌烦又选择了第一篇文章。由于这篇文章已经加载过,它的内容几乎立即显示,应该仿佛回到最开始的状态。但接着发生了奇怪的事情,终于收到了第二篇文章的内容,这个问题很严重,更糟糕的是在开发环境中未必能发现。
Memory Leak
Memory Leak 是最常被忽略的一点。原因是在传统网站的行为, 我们每次切换页面都是整页面重刷,并重新执行javascript,所以不太需要关心内存溢出的问题!但是当我们开发SPA(Single Page Application)网站时,我们是通过javascript来达到切换页面的内容,这时如果有对DOM注册监听事件,而没有在适当的时候把监听事件移除,就有可能选成Memory Leak。比如说在A页面监听body的scroll事件,但页面切换时,没有把scroll的监听事件移除。
Complex State
当有非同步行为时,应用的状态就会变得非常复杂!比如说我们有一支VIP用户才能播放的影片,首先可能要先抓取这部影片的信息,接着我们要在播放时支验证用户是否有权限播放,而用户也有可能再按下播放按钮后又立即按了取消。类似这种都是非同步执行,这时就会有各种复杂的状态需要处理。
Exception Handling
在Javascript中 try/catch 可以捕获同步的异常,但异步的程序就没这么容易,尤其当我们的异步行为很复杂时,这个问题就越加明显
Different kinds of API(各种不同的API)
- DOM Events
- XMLHttpRequest
- Timer
- Fetch
- WebSockets
- ......
上面列的API都是异步的,但他们都有各自的API及写法!如果我们使用RxJS,上面所有的API都可以通过RxJS来处理,就能用同样的API操作。
PS:同样的API是指RxJS的API.
让我们来看个小例子,假设我们想要监听点击事件,但点击一次之后不再监听
- Javascript
const handler = e => document.body.removeEventListener('click', handler)
document.body.addEventListener('click',handler)
- Instead of Rxjs
const {fromEvent} = rxjs
const {take} = rxjs.operators
fromEvent(document.body, 'click') // 注册事件
.take(1) // 只取一次,取完就会移除事件
.subscribe(console.log)
大致上能看得出来我们在使用Rxjs后,不管是针对DOM EVENT 还是上面列的各种API 我们都可以通过Rxjs的API来操作,像示例中用take(n)来设定只取一次,之后就释放内存
Functional Reactive Programming(函数响应式编程)
FRP是一种编程范式,其实就是一种coding的方法论!例如OOP面向对象就是一种编程范式。FRP 其实涵盖了Reactive Programming 及 Functional Programming两种编程思想
Functional Programming(函数式编程)
FP 大部分的人应该多少都有接触过,这也是Rx学习过程中的重点之一,后面预计会花2个篇幅来细讲FP,如果要用一句话来总结FP,那就是用Function来思考我们的问题,以及coding!
Reactive Programming(响应式编程)
如果你使用过Vue开发网站,那应该对这个RP不陌生。RP简单的来说就是当变量或资源发生变动时,由变量或资源自动告诉我们发生变动了
- 发生变动=> 异步 不确定什么时候会发生变动,反正变动时要通知我
- 由变量自动告知我=> vue中的声明式变量