Rxjs流式应用编程(浅浅介绍)
来源自邱邱学长代码及分享https://jsfiddle.net/QattaQ/oj1stspd/10/
其实rxjs这个东西好像是一个蛮庞大的框架。好像在国内不是很流行的样子。。。但是关注度比较高。。里边的编程思想非常有意思。是一种基于时间流的编程。这篇文章也就只是讲讲rxjs是什么。当一个引子之类的(因为我也不太懂呀)。。
思想
rxjs这个框架有点数组的感觉。。不过呢,这个数组的元素是事件。。。这是什么个意思,容我细细道来。。。
假如发生了abcde5个事件。
rxjs会把它当做5个原素,然后加入到一个数组,最后给这个数组加上时间轴。嗯,大功告成,这就是rxjs的主要处理对象Observable
也就是数组+时间轴=Observable
也就是一个事件流
看图,就是这样
这样有什么好处呢?
你可以像处理数组一样处理事件!!
想想就觉得很便捷有木有!!
实例
来看个demo
假如我们要实现一个常规搜索。。。
一般来说是这样
<input id="text"></input> <script> var text = document.querySelector('#text'); text.addEventListener('keyup', (e) =>{ var searchText = e.target.value; // 发送输入内容到后台 $.ajax({ url: `search.qq.com/${searchText}`, success: data => { // 拿到后台返回数据,并展示搜索结果 render(data); } }); }); </script>
上面代码实现我们要的功能,但存在两个较大的问题:
-
多余的请求
当想搜索“爱迪生”时,输入框可能会存在三种情况,“爱”、“爱迪”、“爱迪生”。而这三种情况将会发起 3 次请求,存在 2 次多余的请求。 -
已无用的请求仍然执行
一开始搜了“爱迪生”,然后马上改搜索“达尔文”。结果后台返回了“爱迪生”的搜索结果,执行渲染逻辑后结果框展示了“爱迪生”的结果,而不是当前正在搜索的“达尔文”,这是不正确的。
最终代码为
<input id="text"></input> <script> var text = document.querySelector('#text'), timer = null, currentSearch = ''; text.addEventListener('keyup', (e) =>{ clearTimeout(timer) timer = setTimeout(() => { // 声明一个当前所搜的状态变量 currentSearch = '书'; var searchText = e.target.value; $.ajax({ url: `search.qq.com/${searchText}`, success: data => { // 判断后台返回的标志与我们存的当前搜索变量是否一致 if (data.search === currentSearch) { // 渲染展示 render(data); } else { // .. } } }); },250) }) </script>
但是如果用rxjs实现的话是这个样子
var text = document.querySelector('#text'); var inputStream = Rx.Observable.fromEvent(text, 'keyup') .debounceTime(250) .pluck('target', 'value') .switchMap(url => Http.get(url)) .subscribe(data => render(data));
简单炸了有木有。。
介绍
RxJS中解决异步事件管理的基本概念如下:
Observable可观察对象:表示一个可调用的未来值或者事件的集合
Observer观察者:一个回调函数集合,它知道怎样去监听被Observable发送的值
Subscription订阅:表示一个可观察对象的执行,主要用于取消执行
Operators操作符:纯函数,使得以函数编程的方式处理集合比如:map,filter,merge,scan
观察对象和观察者的关系大致如下
其实也和普通的监听机制差别不大。。
所以也就形成了上面那种数组一样的执行机制。。
具体来体会一下事件流吧。。。
比如我们现在要创建一个关于鼠标移动的流
好,现在观察者已经监听了可观察对象。。
当鼠标移动的时候
形成了这样的事件流。。。。那么我们不能单纯的使用这个流,要获得两个点移动的坐标。
好,这时就是用operator的时候了。也就类似于数组方法,创建一个新流
之后,新事件流是这个样子。
然后,怎么拿到两个点的坐标呢?我们需要再变换一下 这个流。。。也就是用了一个缓冲的方法。。。将两个元素合成为一个元素组。。
最后的流是这个样子
这也就是事件流操作的流程,显而易见,事件流的思想极大地简化了编程的复杂性。代码看起来很有条理,也便于修改。所以这种流式编程的思想也是很值得学习的。。
具体学习的话查看官方api和参考文档
* 参考:
* 官方文档:http://reactivex.io/rxjs/manual/overview.html
* 饿了么团队(让我们一起来学习 RxJS):https://fe.ele.me/let-us-learn-rxjs
* Alloyteam团队(构建流式应用—RxJS详解):http://www.alloyteam.com/2016/12/learn-rxjs