RxJS——函数式编程

本篇通过RxJS的实现原理、基础实现以及实例来一步步分析,提供RxJS较为全面的指引,感受一波使用RxJS编码是怎样的体验

常规方式实现搜索功能

搜索功能是前端开发经常做的,一般的实现方式是:监听文本框的输入事件,将输入的内容发送到后台,最终将后台返回的数据(搜索结果)在前端页面渲染处理


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

1.多余的请求

    当我们想要搜索“笔记本”时,输入框可能会存在三种情况,“笔”、“笔记”、“笔记本”,而这三种情况将发生三次,这样就存在两次多余请求

2.已无用的请求仍然进行

    假如我们一开始搜索了“笔记本”,然后马上改搜索“文具”,后台一开始会先将“笔记本”的搜索结果返回,而不是当前正在搜索的“文具”的结果,这是不正确的

减少多余请求数, 可以通过setTimeout函数节流的方式处理


上面的代码基本满足了只显示当前搜索数据的结果,在发起请求前声明一个当前搜索的状态变量,后台将搜索的内容及结果一起返回,前端判断返回数据和当前搜索是否一致,一致才走到渲染逻辑。但是这样开始显得乱糟糟。接下来使用RxJS实现上面代码功能,如下


可以明显看的出,基于RxJS的实现,代码十分简洁

RxJS基础实现

接下来我们介绍一下怎么创建Observable 与 Observer的呢?

创建Observable

RxJS提供create方法来自定义创建一个Observable,可以使用next来发出流


创建Observer

Observer可以声明next、err、complete方法来处理流的不同状态


最后通过subscribe订阅将Observable与Observer结合起来。


RxJS中流时可以取消的,调用subscribe将返回一个subscription,可以通过调用subscription.unsubscribe()将流进行取消,让流不在产生。

我们也可以换一种实现形式完成上面的功能:


将上面的代码改用链式写法,代码变得十分简洁:


RxJS - Operators

Operators操作(入门)


上面代码相当于创建了流2,最终打印出2。如果现在我们要实现打印结果翻倍,该如何处理呢

方案一?: 改变事件源,让Observable值 *2


方案二?: 改变响应方式,让Observer 处理 *2


优雅方案: RxJS提供了优雅的处理方式,可以在事件源(Observable)与响应者(Observer)之间增加操作流的方法:


map操作符根数组操作符作用是一样的,不同的是这里是将流进行改变,然后将新的流传出去。在RxJS中,把这类操作流的方式称之为Operators(操作).RxJS提供了一系列Operators,像map、reduce、filter等等。操作流将产生新流,从而保持流的不可变性,这也是RxJS函数式编程的一点体现。

到这里,我们知道了流从产生到最终结果,可能经过了一些操作。即Observable 经过一系列 Operators 操作后,到达 Observer

Observable  —— operator1 —— operator2 —— Observer

一系列的Operators操作

RxJS提供了非常多的操作。operators具有静态(static)方法和实例(instance)方法,下面使用Rx.Observable.xx 和 Rx.Observable.prototype.xx 来简单区分,举几个例子说明一下

Rx.Observable.of

of可以将普通数字流转换成流式数据Observable。如上面的Rx.Observable.of(2)。

Rx.Observable.fromEvent

除了数值外,RxJS还提供了关于事件的操作,fromEvent可以用来监听事件。当事件触发时,将事件转化成可流动的Observable进行传输。下面示例表示:监听文本框的keyup事件,触发keyup可以


Rx.Observable.prototype.map

map方法跟我们平常使用的方式是一样的,不同的只是这里是将流进行改变,然后将新的流传出去。


Rx.Observable.prototype.mergeMap

mergeMap也是RxJS常用的接口,作用是将分流调整回主干上,最终分支上的数据流都经过主干的其他操作。

Rx.Observable.prototype.switchMap

switchMap 与 mergeMap 都是将分支流疏通到主干上,而不同的地方在于switchMap只会保留最后的流,而抛弃之前的流

Rx.Observable.prototype.debounceTime

debounceTime操作可以操作一个时间戳,表示经过Times毫秒后,没有流入新值,那么才将值传入下一个,否则这个值被丢弃

接下来我们再把一开始的监听事件详细讲一下:


这里我们并不想输出事件,而想拿到文本输入值,请求搜索,最终渲染出结果。这里涉及到两个操作,简单理解一下

RxJS.Observable.prototype.pluck('target', 'value')   //将输入的event,输出成event.target.value

RxJS.Observable.prototype.mergeMap()   //将请求搜索结果输出给Observer上进行渲染


上面的代码实现了简单搜索呈现,但同样存在一开始提到的两个问题,那么如何减少请求以及取消已无用的请求呢?

RxJS.Observable.prototype.debounceTime(TIMES)

表示经过TIMES毫秒后,没有新的流入值,那么才将值流入下一个环节。这个与前面的setTimeout来实现函数节流的方式效果一样

RxJS.Observable.prototype.switchMap()

使用switchMap替换mergeMap,能够取消上一个已无用的请求,只保留最后的请求结果流,这样就确保处理展示的是最后的搜索结果


总结:本篇作为RxJS入门篇到这里就结束了,RxJS作为一个库,可以与众多框架结合使用,但并不是每一种场合都需要使用到RxJS。复杂的数据来源,异步多的情况下才能更好凸显RxJS作用

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值