一.RxJS 初试
- 在 javascript 中的试炼
1 | const height = document.getElementById('height'); |
- RxJs 的威力在于合并和转换流,实例如下
(1)html
1 | <input type="text" id="length"/> |
(2)js
1 | const length = document.getElementById('height'); |
- 事件流:理解 Rx 的关键是要把任何变化想象成事件流
二.RxJS 常见操作符
1.常见创建类操作符
- from:可以把数组、Promise、以及 Iterable 转化为 Observable
- fromEvent:可以把事件转化为 Observable
- of:接受一系列的数据,并把它们 emit 出去
- 如可以使用
object$ = Rx.Observable.of({id:1,value:20})
转化对象,使用的时候应该是 object.value 或 object.id 的方式
- 如可以使用
2.常见转换操作符
- map
- 是 mapTo、pluck 操作符的根本
- 举例将上述 pluck 操作符取 target 的 value 值转换成使用 map 操作符
1 | const width$ = Rx.Observable.fromEvent(width, 'keyup').map(ev=>ev.target.value); |
- 在 angular 中灵活使用 Observable 如下
1 | // 定义一个发起网络请求获取Observable的方法 |
mapTo
比如点击按钮事件或其他事件,我们不需要关注其值内容,只需要知道发生了即可,可以使用 mapTo 定义成一个固定值
实例代码
1 | const width$ = Rx.Observable.fromEvent(width, 'keyup').mapTo(1);//此时执行keyup事件,width$的值即为1 |
- pluck
3.Observable 的性质
- Observable 有三种状态(即 subscribe 的三个参数):next、error、complete
- next 是正常执行时的内容,subscribe 的第一个参数
- error 是当执行时出错,或监听了 throw 类型 Observable 时的执行内容,subscribe 的第二个参数
- complete 是 Observable 执行结束时的内容,subscribe 的第三个参数
- 特殊的 Observable:永不结束、Never、Empty(结束但不发射)、Throw
- Never 类型 Observable 表示不会发生也永远不会结束,会在执行过程中导致,也可直接通过 Rx.Observable.error(‘xxx’)的方式声明,结果不会执行 next、error、complete 中任何一个阶段
- Empty 类型 Observable 不会发射元素会直接结束,会在执行过程中导致,也可以通过 Rx.Observable.empty()的方式声明,结果不会执行 next、error,会执行 complete 阶段
- Throw 类型 Observable 直接进入 error 状态,会在执行过程中抛出异常导致,也可以直接通过 Rx.Observable.throw(‘xxx’)的方式声明,结果只会执行 error 阶段
4.常见工作操作符:do
- do 操作符用于在流处理期间对数据进行操作,实例如下
1 | const interval$ = Rx.Observable.interval(100) |
5.常见变换类操作符:scan
- scan(()=>{})接受一个函数,参数 1 是上次处理后的结果,参数 2 是新值内容。实例代码
1 | const interval$ = Rx.Observable.interval(100) |
6.常见数学类操作符:reduce
- reduce 是将流计算结果做统一的最后处理并发射,实例代码
1 | const interval$ = Rx.Observable.interval(100) |
7.过滤类操作符:filter、take、first/last、skip…
- take(num)表示取流中前 num 个
- filter(()=>{})表示对流处理的放行判断,如果满足条件则放行,不满足条件则不放行
1 | const interval$ = Rx.Observable.interval(100) |
- first()表示取流第一个,相当于 take(1)
- last()表示取流最后一个
- skip(num)表示跳过前 num 个
1 | const interval$ = Rx.Observable.interval(100) |
8.常见创建类操作符:Interval、Timer
- Interval 实例代码
1 | const interval$ = Rx.Observable.interval(100).take(3); |
- Timer 实例代码
1 | const timer$ = Rx.Observable.timer(100,200);//表示100毫秒之后启动,之后以200毫秒的频率一直发送 |
9.实例:自行给 rxjs 中 Observable 添加 debug 方法
- 通过 Observable 的原型中定义 debug 方法返回 Observable 对象
1 | import {Observable} from 'rxjs/Observable'; |
10.过滤类操作符:debounce、debounceTime
- debounce:比 debounceTime 灵活,debounceTime 只能设定固定的毫秒间隔,而 debounce 可以通过接受的 function 设定毫秒间隔
1 | const length$ = Rx.Observable.fromEvent(length,'keyup').pluck('target','value').debounce(()=>Rx.Observable.interval(300));//可以自行修改function返回内容从而决定滤掉的内容 |
- debouceTime(num):时间滤波器,表示只关注大于等于 num 毫秒间隔的事件内容
1 | const length$ = Rx.Observable.fromEvent(length,'keyup').pluck('target','value').debounceTime(300); |
- 执行图片
11.过滤类操作符:distinct、distinctUtilChanged
- distinct:整个序列中,过滤一样的,保留不一样的(要求序列中没有重复的元素)
1 | const length$ = Rx.Observable.fromEvent(length,'keyup').pluck('target','value').distinct();//过滤掉整个流中重复的元素 |
- distinctUtilChanged:只跟前一个元素比,过滤一样的,保留不一样的
1 | const length$ = Rx.Observable.fromEvent(length,'keyup').pluck('target','value').distinctUtilChanged();//过滤掉流中前一个重复的元素 |
- 执行图片
12.合并类操作符:merge、concat、startWith
- merge:在整个序列中按照流运行状态进行合并
- concat:在整个序列中将流前后拼接(如拼接的第一个流是无尽流,则永远只会输出第一个流内容,因为第二个流永远不会发生,第一个流没有执行完)
- startWith:设定流发射的初始值
- 执行图片
13.合并类操作符:combineLatest、withLatestFrom、zip
- 通过 combineLatest 可以对两个流进行对应的处理操作,实例请参照开头计算面积
- zip 有对齐的感觉,将两个流对应位置的元素进行处理操作,慢的流决定最终 zip 生成流的速度
- withLatestFrom 当基准流改变时才会进行流处理,使用方式是基准流.withLatestFrom(其他流),如下
1 | const merged$ = length$.withLatestFrom(width$); |
- 区别:zip 有对齐的特性,withLatestFrom 是以源事件流为基准,combineLatest 是无论任何一个流发生改变时都会处理