rxjs6 Filtering Operators

老子叫甜甜 提交于 2020-02-25 18:43:39

debounce / debounceTime

防抖, 一直输入的情况下, 只有输入间隔大于200ms时发送数据, 减少无用请求数

  change$.pipe(
    debounce(() => interval(200))
  ).subscribe(console.log)
  change$.pipe(
    debounceTime(200)
  ).subscribe(console.log)


distinct

去重, 可以传入一个 keySelector 的函数

// 1,2,3
of(1, 2, 1, 2, 3).pipe(
  distinct()
).subscribe(console.log)

// { name: 'a' } { name: 'b' }
of(
  {name: 'a',}, {name: 'b'}, {name: 'a'}
).pipe(
  distinct(v => v.name)
).subscribe(console.log)



distinctUntilChanged

完整的去重需要维护一个set, 为了节省内存, 可以只和上一个比较, 常用于已经排序的情况

of(
  {age: 4, name: 'Foo'},
  {age: 7, name: 'Bar'},
  {age: 5, name: 'Foo'},
  {age: 6, name: 'Foo'},
).pipe(
  distinctUntilChanged((p, q) => p.name === q.name),
).subscribe(x => console.log(x));

// { age: 4, name: 'Foo' }
// { age: 7, name: 'Bar' }
// { age: 5, name: 'Foo' }


distinctUntilKeyChanged

比较属性值的简写

of(
  {age: 4, name: 'Foo'},
  {age: 7, name: 'Bar'},
  {age: 5, name: 'Foo'},
  {age: 6, name: 'Foo'},
).pipe(
  // distinctUntilChanged((p, q) => p.name === q.name),
  distinctUntilKeyChanged('name'),
).subscribe(x => console.log(x));


elementAt

返回流中指定索引的数据

// 3
let s = interval(200)
s.pipe(
  elementAt(3)
).subscribe(console.log)


filter

和数组的类似

// 1 3 5 7 9
range(1,10).pipe(
  filter(x=>x%2)
).subscribe(console.log)


first

取流中的第一个

// 1
range(1,10).pipe(
  first()
).subscribe(console.log)


ignoreElements

忽略所有元素, 直到完成

// the end
range(1, 10).pipe(
  ignoreElements()
).subscribe(
  word => console.log(word),
  err => console.log('error:', err),
  () => console.log('the end'),
)


audit

有点像防抖, 在内层流发出数据时, 会发出外层最新的值

let s = interval(1000)
s.pipe(
  audit(()=>interval(5000))
).subscribe(console.log)
// 4
// 9
// 14
// 19
// 24


auditTime


let s = interval(1000)
s.pipe(
  // audit(()=>interval(5000))
  auditTime(5000)
).subscribe(console.log)
// 4
// 9
// 14
// 19
// 24


last

有限流最后的元素

// 10
range(1, 10).pipe(
  last()
).subscribe(console.log)


sample

内层流发出数据时, 将外层流最新的数据发送出去, 如果数据没有更新, 不发送, 如果外层流结束了, 则直接结束

const source = zip(
  //emit 'Joe', 'Frank' and 'Bob' in sequence
  from(['Joe', 'Frank', 'Bob']),
  //emit value every 2s
  interval(2000)
)
const example = source.pipe(
  tap(v => console.log('tap', v)),
  sample(interval(100))
).subscribe(console.log);

// tap [ 'Joe', 0 ]
// [ 'Joe', 0 ]
// tap [ 'Frank', 1 ]
// [ 'Frank', 1 ]
// tap [ 'Bob', 2 ]

区分是否是拖拽, 只有在鼠标抬起时才会知道结果

merge(
  mouseDown$.pipe(mapTo(false)),
  mouseMove$.pipe(mapTo(true))
).pipe(
  sample(mouseUp$)
).subscribe(
  isDragging => {
    console.log('Were you dragging?', isDragging);
  }
);


sampleTime

const example = source.pipe(
  tap(v => console.log('tap', v)),
  // sample(interval(100))
  sampleTime(100)
).subscribe(console.log);

// tap [ 'Joe', 0 ]
// [ 'Joe', 0 ]
// tap [ 'Frank', 1 ]
// [ 'Frank', 1 ]
// tap [ 'Bob', 2 ]


single

判断流中的数据是否只含有一个

of(1).pipe(
  single()
).subscribe(console.log) // 1

of().pipe(
  single()
).subscribe(console.log,
  err => console.log('err1') // err1
); 
of(1, 2).pipe(
  single()
).subscribe(console.log,
  err => console.log('err2') // err2
)


skip / skipLast

从前面跳过和从后面跳过

// 4 5 6 7 8
range(1, 10).pipe(
  skip(3),
  skipLast(2)
).subscribe(console.log)


 


skipUntil

内层流输出数据后, 外层流开始输出

// 19 20 21 22 23 ...
interval(100).pipe(
  skipUntil(interval(2000))
).subscribe(console.log)


skipWhile

跳过刚开始满足条件的值

// 5 6 7 8 9 10
range(1, 10).pipe(
  skipWhile(x => x < 5)
).subscribe(console.log)


take

取开始的指定数目的值

// 1 2 3
range(1, 10).pipe(
  take(3)
).subscribe(console.log)


takeLast

取最后的几个值, 必须是有限流

// 8 9 10
range(1, 10).pipe(
  takeLast(3)
).subscribe(console.log)


takeUntil

在内层数据发出后停止取值

// 0 1 2 3 
interval(100).pipe(
  takeUntil(interval(500))
).subscribe(console.log)


takeWhile

取满足条件的值, 注意, 当条件不满足时, 即使后面的数值条件已经满足也不会输出

// 1 2
of(1, 2, 6, 3, 4).pipe(
  takeWhile(x => x < 5)
).subscribe(console.log)

throttle

防抖

  let input = document.getElementById('input')
  let change$ = fromEvent(input, 'input').pipe(
    map(e => e.target.value)
  )

  change$.pipe(
    throttle(()=>interval(100))
  ).subscribe(console.log)


throttleTime

  change$.pipe(
    // throttle(()=>interval(100))
    throttleTime(100)
  ).subscribe(console.log)

 

audit / throttle区别

audit会取新值, throttle会取旧值, 在连续输入字符串时, audit的字符串长度比throttle长

  let input = document.getElementById('input')
  let change$ = fromEvent(input, 'input').pipe(
    map(e => e.target.value.length)
  )

  change$.pipe(
    // throttle(()=>interval(100))
    throttleTime(100)
  ).subscribe(v => console.log('throttleTime', v))
  change$.pipe(
    // throttle(()=>interval(100))
    auditTime(100)
  ).subscribe(v => console.log('auditTime', v))

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!