「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战」
take
take 是最简单的过滤操作符,它的意思是取 n 个值,传入的参数为取的个数,举个例子:
interval(1000).pipe(take(3)).subscribe(x => console.log(x));
// 0
// 1
// 2
弹珠图:
takeLast
取最后的 n 个值,使用 takeLast 会将值缓存在内存中,等到流结束时取最后的值,它不可以用于不会终止的流,在无尽的流上使用 takeLast 永远不会发出数据。举个例子:
range(1, 100).pipe(takeLast(3)).subscribe(x => console.log(x));
弹珠图:
takeUntil
takeUntil 接收一个终止 Observable,当终止 Observable 产生数据时,原始 Observable 会停止,举个例子:
interval(1000).pipe(takeUntil(fromEvent(document, 'click'))).subscribe(x => console.log(x));
点击之后会停止定时数据打印。
takeUntil 是一个很有用的操作符,它的一个重要作用是可以停止订阅:我们在一个页面或组件中可能创建很多订阅,我们需要在卸载时销毁订阅,有了 takeUntil,我们就可以在添加订阅时设置统一的 takeUntil 条件,在卸载时触发这个条件停止所有的事件订阅。
takeUntil 的弹珠图:
takeWhile
takeWhile 是当满足条件时取值,一旦遇到不满足条件的数据时直接终止:
of(2, 3, 4, 5, 6).pipe(takeWhile(x => x < 4)).subscribe(console.log);
// 2
// 3
对应的弹珠图:
skip
skip 是与 take 相反的操作符,skip 的意思是跳过,使用 skip 可以实现跳过 n 个数据不取,举个例子:
of(1, 2, 3, 4, 5).pipe(skip(3)).subscribe(console.log);
// 4
// 5
skip 的弹珠图:
skipLast
与 take 对应的,skip 也有一系列操作符,分别对应了不同的跳过方式,这里先来看 skipLast,skipLast 为跳过后面 n 个值,它的实现和 takeLast 类似,当数据发送完成后跳过最后的值发出其他的值:
of(1, 2, 3, 4, 5).pipe(skipLast(2)).subscribe(x => console.log(x));
// 1
// 2
// 3
skipLast 的弹珠图:
skipUntil
skipUntil 也是接收一个终止 Observable,当终止 Observable 产生数据时停止跳过,即从终止 Observable 发数据之后开始正式取值,我们把之前 takeUntil 使用的例子换成 skipUntil:
interval(1000).pipe(skipUntil(fromEvent(document, 'click'))).subscribe(x => console.log(x));
这里实现的是一个相反的效果,点击之后才开始打印。
弹珠图:
skipWhile
skipWhile 是当满足条件时跳过,一旦遇到不满足条件时开始发出:
of(2, 3, 4, 5, 6).pipe(skipWhile(x => x < 4)).subscribe(console.log);
// 4
// 5
// 6
弹珠图:
first
first 也是很常用的操作,意思是只取一个,实际上就是 take(1) 的效果:
of(1, 2, 3, 4).pipe(first()).subscribe(console.log);
// 1
弹珠图:
last
last 与 first 的效果是相反的,它是取最后一个,也就是 takeLast(1) 的效果:
of(1, 2, 3, 4).pipe(last()).subscribe(console.log);
// 4
弹珠图:
filter
filter 是按照条件来过滤,从语义上来说 filter 应该是最基础的过滤操作符了,而它的语法也是符合我们的常规认知,熟悉数组的 filter 就知道该怎么写了:
of(0, 1, 2, 3, 4).pipe(filter(x => x % 2 === 1)).subscribe(console.log);
// 1
// 3
filter 的弹珠图:
elementAt
elementAt 类似数组的下标索引,表示输出指定 index 的值(index 从 0 开始),这里需要注意与数组的区别,流可以是无限的,但是指定的位置是有限的,因此 elementAt 可以用于无限流,但是对于有限流 index 不允许超限,举个例子:
fromEvent(document, 'click').pipe(elementAt(2)).subscribe(x => console.log(x));
这里是一个可以无限点击的流,我们可以在第三次点击时看到打印。
弹珠图:
ignoreElements
忽略全部内容,只传递异常和结束信息,可以用于不关注数据只关注异常的场景,举个例子:
of(1, 2, 3, 4).pipe(ignoreElements()).subscribe(
v => console.log(v),
err => console.log('err:', err),
() => console.log('end'),
);
// end
弹珠图:
以上介绍了一部分常用的过滤操作符,重点看了 take 和 skip 系列操作服,这些过滤操作在实际开发中很常用,此外还有一些高级的过滤操作符下一篇会继续介绍。