过滤操作符
# debounceTime
定义:
public debounceTime(dueTime: number, scheduler: Scheduler): Observable
可能对于有过一定js
开发经验的小伙伴应该会知道debounce
防抖函数,那么这个时候会有小伙伴问了,它不会就和debounce
差不多吧?没错,他的功能与debounce
防抖函数差不多,不过还是有一点差别的。
只有在特定的一段时间经过后并且没有发出另一个源值,才从源 Observable
中发出一个值。
也就是说,假设一个数据源每隔一秒发送一个数,而我们使用了debounceTime
操作符,并设置了延时时间,那么在数据源发送一个新数据之后,如果在延时时间内数据源又发送了一个新数据,这个新的数据就会被先缓存住不会发送,等待发送完数据之后并等待延时时间结束才会发送给订阅者,不仅如此,在延时时间未到的时候并且已有一个值在缓冲区,这个时候又收到一个新值,那么缓冲区就会把老的数据抛弃,放入新的,然后重新等待延时时间到达然后将其发送。
const source = Rx.Observable.interval(1000).take(3);
const result = source.debounceTime(2000);
result.subscribe(x => console.log(x));
2
3
从代码来看,我们不妨猜测一下,最后打印的结果是什么?
首先我们创建了一个每秒发送一个数字并且只会发三次的数据源,然后用debounceTime
处理了一下,并设置延时时间为2秒,这个时候我们观察打印的数据会发现,程序启动之后的前三秒没有数据打印,等到五秒到了之后,打印出一个2,接着就没有再打印了,这是为什么?
答案是数据源会每秒依次发送三个数0、1、2,由于我们设定了延时时间为2秒,那么也就是说,我们在数据发送完成之前都是不可能看到数据的,因为发送源的发送频率为1秒,延时时间却有两秒,也就是除非发送完,否则不可能满足发送源等待两秒再发送新数据,每次发完新数据之后要等两秒之后才会有打印,所以不论我们该数据源发送多少个数,最终订阅者收到的只有最后一个数。
# throttleTime
定义:
public throttleTime(duration: number, scheduler: Scheduler): Observable<T>
介绍了防抖怎么能忘了它的老伙伴节流呢?
该操作符主要能力跟我们认知的节流函数也是一致的,就是它会控制一定时间内只会发送一个数据,多余的会直接抛弃掉。唯一和防抖操作符不一致的地方就在于它对于第一个值是不会阻塞的。
const source = Rx.Observable.interval(1000).take(6);
const result = source.throttleTime(2000);
result.subscribe(x => console.log(x));
// 0
// 3
2
3
4
5
6
打印结果如上所示,其实效果也很容易解释,代码中创建了一个数据源每秒发送一个从0开始递增的数,总共发送6个也就是0-5,并使用throttleTime
设置两秒,订阅者接收第一个值时不会被阻塞,而是接收完一个之后的两秒里都拿不到值,也就是在第四秒的时候才能拿到3。
# distinct
定义:
public distinct(keySelector: function, flushes: Observable): Observable
这个操作符也十分好理解,一句话可以概括,使用了该操作符,那么订阅者收到的数据就不会有重复的了,也就是它是用来过滤重复数据的。
const source = Rx.Observable.from([1, 2, 3, 2, 4, 3]);
const result = source.distinct();
result.subscribe(x => console.log(x));
2
3
最终程序运行结果为:1、2、3、4,重复的数直接被过滤了。
# filter
定义:
public filter(predicate: function(value: T, index: number): boolean, thisArg: any): Observable
这种基本应该没啥好介绍的了,与我们理解的数组filter
方法并无差别,只是用的地方不一致。
const source = Rx.Observable.from([1, 2, 3, 2, 4, 3]);
const result = source.filter(x => x !== 3);
result.subscribe(x => console.log(x));
2
3
程序运行结果就是除了3以外的其他值都被打印出来。
# first
定义:
public first(predicate: function(value: T, index: number, source: Observable<T>): boolean, resultSelector: function(value: T, index: number): R, defaultValue: R): Observable<T | R>
只发出由源 Observable
所发出的值中第一个(或第一个满足条件的值)。
这个也和上面差不多,基本看介绍就能懂,这里就不再多赘述了。
# take
定义:
public take(count: number): Observable<T>
只发出源 Observable
最初发出的的N个值 (N = count)
。
这个操作符可谓是在前面出现了很多次了,还挺常见的,用于控制只获取特定数目的值,跟interval
这种会持续发送数据的配合起来就能自主控制要多少个值了。
# skip
定义:
public skip(count: Number): Observable
返回一个 Observable
, 该 Observable
跳过源 Observable
发出的前N个值(N = count)
。
举个栗子来说就是,假设这个数据源发送6个值,你可以使用skip
操作符来跳过前多少个。
const source = Rx.Observable.from([1, 2, 3, 2, 4, 3]);
const result = source.skip(2);
result.subscribe(x => console.log(x));
2
3
打印结果为:3、2、4、3,跳过了前面两个数。
# 其他过滤操作符
官方提供的操作符还是挺多的,这里就不一一介绍了,感兴趣可以去官网查看:过滤操作符。
debounce
distinctKey
distinctUntilChanged
distinctUntilKeyChanged
elementAt
ignoreElements
audit
auditTime
last
sample
sampleTime
single
skipLast
skipUntil
skipWhile
takeLast
takeUntil
takeWhile
throttle