Rxjs流式应用编程(浅浅介绍)

来源自邱邱学长代码及分享https://jsfiddle.net/QattaQ/oj1stspd/10/

其实rxjs这个东西好像是一个蛮庞大的框架。好像在国内不是很流行的样子。。。但是关注度比较高。。里边的编程思想非常有意思。是一种基于时间流的编程。这篇文章也就只是讲讲rxjs是什么。当一个引子之类的(因为我也不太懂呀)。。

思想

rxjs这个框架有点数组的感觉。。不过呢,这个数组的元素是事件。。。这是什么个意思,容我细细道来。。。

假如发生了abcde5个事件。

rxjs会把它当做5个原素,然后加入到一个数组,最后给这个数组加上时间轴。嗯,大功告成,这就是rxjs的主要处理对象Observable

也就是数组+时间轴=Observable

也就是一个事件流

看图,就是这样

image

这样有什么好处呢?

你可以像处理数组一样处理事件!!

想想就觉得很便捷有木有!!

实例

来看个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>

 

上面代码实现我们要的功能,但存在两个较大的问题:

  1. 多余的请求
    当想搜索“爱迪生”时,输入框可能会存在三种情况,“爱”、“爱迪”、“爱迪生”。而这三种情况将会发起 3 次请求,存在 2 次多余的请求。

  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

观察对象和观察者的关系大致如下

image

其实也和普通的监听机制差别不大。。

所以也就形成了上面那种数组一样的执行机制。。

 

具体来体会一下事件流吧。。。

比如我们现在要创建一个关于鼠标移动的流

image

好,现在观察者已经监听了可观察对象。。

当鼠标移动的时候

image

形成了这样的事件流。。。。那么我们不能单纯的使用这个流,要获得两个点移动的坐标。

好,这时就是用operator的时候了。也就类似于数组方法,创建一个新流

image

之后,新事件流是这个样子。

image

然后,怎么拿到两个点的坐标呢?我们需要再变换一下 这个流。。。也就是用了一个缓冲的方法。。。将两个元素合成为一个元素组。。

image

最后的流是这个样子

image

 

这也就是事件流操作的流程,显而易见,事件流的思想极大地简化了编程的复杂性。代码看起来很有条理,也便于修改。所以这种流式编程的思想也是很值得学习的。。

具体学习的话查看官方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

posted @ 2017-05-31 14:40  Taniffer  阅读(1361)  评论(0编辑  收藏  举报