07RxJS过滤类操作符

2021-01-07  本文已影响0人  learninginto
audit(节流)

频繁地触发某一事件,设置其在规定的时间内只触发一次,达到节流的效果(用于搜索框中请求数据等)

在定时器发出值之前,会忽略所有源Observalbe发出的值,直到定时器发出值,会推送源Observalbe最近发出的一次值

const clicks = fromEvent(document, 'click').pipe(pluck('clientX'))
const result = clicks.pipe(audit(ev => interval(2000)))
result.subscribe(x => console.log(x))

如果在2秒内频繁地触发click事件,audit只会把最近的一次发送出来。

auditTime

类似audit,如果只用到定时的作用,auditTime更方便。重写上面的例子:

const clicks = fromEvent(document, 'click').pipe(pluck('clientX'))
const result = clicks.pipe(auditTime(2000))
result.subscribe(x => console.log(x))
throttle(节流)

不同于audit的是,throttle有第二个参数,接收一个配置项,控制节流函数的触发时期

const interval$ = interval(100)
const result = interval$.pipe(throttle(ev => interval(2000)))
result.subscribe(x => console.log(x))

* 配置项
```js
const defaultThrottleConfig:ThrottleConfig = {
    leading:true, //节流开始前调用,默认为true
    trailing:false //节流开始后调用,默认为false
}
const interval$ = interval(100)
const result = interval$.pipe(throttle(ev => interval(2000), { leading: false, trailing: true }))
result.subscribe(x => console.log(x))
//20
//40
//60
//……
throttleTime

类似throttle

const interval$ = interval(500)
const result = interval$.pipe(throttleTime(2000))
result.subscribe(x => console.log(x))
//0
//21
//42
//……
debounce(防抖)

当源Observable持续发送流,直到间隔的时间大于给定的时间,才执行最后一次(用于监听滚动条事件等)

与audit的区别:

  1. audit是否发出值取决于timer是否发出值
  2. debounce是否发出值取决源Observable的发射间隔是否大于给定的timer
const clicks = fromEvent(document, 'click')
const result = clicks.pipe(debounce(() => interval(1000)))
result.subscribe(x => console.log(x))
debounceTime

类似debounce,重写上面的例子:

const clicks = fromEvent(document, 'click')
const result = clicks.pipe(debounceTime(2000))
result.subscribe(x => console.log(x))
distinct(去重)

依次发出源Observable的值,只是每次只发出与之前不同的值(或者之前从没出现过的值)

of(1, 1, 2, 2, 2, 3, 4).pipe(distinct()).subscribe(x => console.log(x))
//1 2 3 4

还可以指定过滤函数

interface Person{
    age:number,
    name:string
}
of<Person>(
  { age: 4, name: 'Foo' },
  { age: 7, name: 'Bar' },
  { age: 5, name: 'Foo' }
).pipe(
  distinct((p: Person) => p.name),
).subscribe(x => console.log(x))
//{age: 4, name: "Foo"}
//{age: 7, name: "Bar"}
distinctUntilChanged

当源Observable发出了与上一次不同的值时,才把当前值推送出去

of(1, 1, 2, 2, 1, 1, 2, 3).pipe(distinctUntilChanged())
.subscribe(x => console.log(x))
//1 2 1 2 3

还可以指定过滤函数

interface Person {
  age: number,
  name: string
}
of<Person>(
  { age: 4, name: 'Foo' },
  { age: 7, name: 'Bar' },
  { age: 5, name: 'Foo' }
).pipe(
  distinctUntilChanged((p: Person, q: Person) => p.name === q.name),
).subscribe(x => console.log(x))
//{age: 4, name: "Foo"}
//{age: 7, name: "Bar"}
//{age: 5, name: "Foo"}
distinctUntilKeyChanged

当源Observable发出的值,它的key与上一次的key不同时,才把当前值推送出去(与上面的操作效果一样,只不过是换了一个操作符)

of<Person>(
  { age: 4, name: 'Foo' },
  { age: 7, name: 'Bar' },
  { age: 5, name: 'Foo' }
).pipe(
  distinctUntilKeyChanged('name'),
).subscribe(x => console.log(x))

更精细的匹配

of<Person>(
  { age: 4, name: 'Foo' },
  { age: 7, name: 'Bar' },
  { age: 5, name: 'Foo' }
).pipe(
  distinctUntilKeyChanged('name', (x: string, y: string) => x.substring(0, 3) === y.substring(0, 3)),
).subscribe(x => console.log(x))
//{age: 4, name: "Foo"}
//{age: 7, name: "Bar"}
//{age: 5, name: "Foo"}

比较的只是{ag,所以全部打印

elementAt

发出指定索引的那个值

const clicks = fromEvent(document, 'click')
const result = clicks.pipe(elementAt(2));
result.subscribe(x => console.log(x))

这里可能会点击很多次,但只会触发第二次的click事件

ignoreElements

忽略源Observable发出的所有值,除了complete和error

of('you', 'talking', 'to', 'me').pipe(ignoreElements())
  .subscribe(
    word => console.log(word),
    err => console.log('error', err),
    () => console.log('the end')
  )
//the end
filter

类似数组的filter

const clicks = fromEvent(document, 'click')
const clicksOnDivs = clicks.pipe(filter(ev => (ev.target as HTMLElement).tagName === 'DIV'))
clicksOnDivs.subscribe(x => console.log(x))
first

只取第一个发出的值,与first对应的操作符是last.

const clicks = fromEvent(document, 'click')
const clicksOnDivs = clicks.pipe(first())
clicksOnDivs.subscribe(x => console.log(x))

也可以指定第一个值符合的条件

const clicks = fromEvent(document, 'click')
const clickOnDivs = clicks.pipe(first(ev => (ev.target as HTMLElement).tagName === 'DIV'))
clicksOnDirs.subscribe(x => console.log(x))
last
of('one', 'two', 'three').pipe(last()).subscribe(res => console.log(res))
//three
sample

忽略源Observable发出的值,直到另一个Observable发出值,才推送源Observable最近发出的值

const seconds = interval(1000)
const clicks = fromEvent(document, 'click')
const result = seconds.pipe(sample(clicks))
result.subscribe(x => console.log(x))

定时器持续在计算,但未触发,直到click才推送流

sampleTime

每隔指定的时间发出最近的一个值

const seconds = interval(1000)
const result = seconds.pipe(sampleTime(3000))
result.subscribe(x => console.log(x))
//1
//4
//7
single

类似first,发出第一个值,但如果源Observalbe有多个值,就会直接进入error

//从1开始,同时发起5个数字
const numbers = range(1, 5).pipe(single())
numbers.subscribe(x => console.log(x), e => console.log('error'))
//error

也可以指定过滤函数

const numbers = range(1, 5).pipe(single(item => item === 3))
numbers.subscribe(
  x => console.log('get result', x),
  e => console.log('error'))
//get result 3

筛选出的结果必须只有一个符合的值,否则也是直接进入error

const numbers = range(1, 5).pipe(single(item => item > 3))
numbers.subscribe(
  x => console.log('get result', x),
  e => console.log('error'))
//error
skip

跳过前面的n个值开发推送数据

const source = interval(1000)
const example = source.pipe(skip(3));
const subscribe = example.subscribe(val => console.log(val))
//3 
//4 
//5
skipLast

忽略最后的n个值

const many = range(1, 5)
const skipLastTwo = many.pipe(skipLast(2))
skipLastTwo.subscribe(x => console.log(x))

从1开始,发送5个值,通过pipe忽略最后的2个值,所以打印1,2,3

skipUntil

一直忽略源Observable发出的值,直到另一个Observable发出值为止

const intervalObservalbe = interval(1000)
const click = fromEvent(document, 'click')
const emitAfterClick = intervalObservalbe.pipe(skipUntil(click))
const subscribe = emitAfterClick.subscribe(value => console.log(value))

第一个Observalue虽然一直在计时,但它会等到当第二个Observalbe发出值的时候才推送出来,并且一直执行下去,打印的时间以第二个Observalbe推送的时间为准。

skipWhile

忽略所有符合条件的值

const source = interval(1000);
const example = source.pipe(skipWhile(val => val < 5))
const subscribe = example.subscribe(val => console.log(val))
//6 7 8 9 10 ……
take

只取前n个值

const intervalCount = interval(1000);
const takeFive = intervalCount.pipe(take(1))
takeFive.subscribe(x => console.log(x))
//1
//2
//3
takeLast

只取最后n个值

const intervalCount = range(1, 100)
const takeFive = intervalCount.pipe(takeLast(3))
takeFive.subscribe(x => console.log(x))
//98
//99
//100
takeUntil

不断推送源Observable发出的值,直到另一个Observalbe发出值为止

const source = interval(1000)
const clicks = fromEvent(document, 'click')
const result = source.pipe(takeUntil(clicks))
result.subscribe(x => console.log(x))
takeWhile

只取符合条件的值

const source = range(1, 8)
const example = source.pipe(takeWhile(val => val <= 4))
const subscribe = example.subscribe(val => console.log(val))
//1
//2
//3
//4
上一篇 下一篇

猜你喜欢

热点阅读