I'm using mousemove event to create an observable.
Observable.fromEvent(document, 'mousemove')
I need to emit every 10-th event. What do I do?
I can think of four different ways to do it:
bufferCount()
Observable.range(1, 55)
.bufferCount(10)
.map(arr => arr[arr.length - 1])
.subscribe(val => console.log(val));
windowCount()
Observable.range(1, 55)
.windowCount(10)
.switchMap(window => window.takeLast(1))
.subscribe(val => console.log(val));
debounce()
let source = Observable.range(1, 55).publish();
source
.debounce(val => debounceNotifier)
.subscribe(val => console.log(val));
let debounceNotifier = source
.bufferCount(10)
.publish();
debounceNotifier.connect();
source.connect();
scan()
Observable.range(1, 55)
.scan((acc, val) => {
if (acc.length === 10) {
acc = [];
}
acc.push(val);
return acc;
}, [])
.filter(acc => acc.length === 10)
.map(acc => acc[acc.length - 1])
.subscribe(val => console.log(val));
However, when using scan()
it'll will discard the last value 55
.
See demo for all of them: https://jsbin.com/yagayot/14/edit?js,console
Here's an even simpler and considerably faster approach, which I tested with RxJS 6:
range(1, 10000000)
.pipe(
filter(function(value, index) {
return index % 10 === 0;
}),
);
This code is twice as fast as the bufferCount
and windowCount
approaches in the other answer: https://jsperf.com/observable-nth/1
This is likely because the filter
operator uses a simple counter, instead of having to keep a buffer of the last n
elements. I assume this is even faster when n
is larger or the elements themselves are bigger. With RxJS 6, you can also easily make this into your own custom operator:
const takeEveryNth = (n: number) => filter((value, index) => index % n === 0);
// usage: rxjs.range(1, 10000000).pipe(takeEveryNth(10));
It is also the code used in the official docs explaining how to create custom operators: https://github.com/ReactiveX/rxjs/blob/6.2.2/doc/pipeable-operators.md
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With