如何发出每个第 n 个值?
How to emit every n-th value?
我正在使用 mousemove 事件创建一个可观察对象。
Observable.fromEvent(document, 'mousemove')
我需要每 10 个事件发出一次。我该怎么办?
我可以想到四种不同的方法:
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));
去抖动()
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();
扫描()
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));
但是,当使用 scan()
时,它将丢弃最后一个值 55
。
这是我用 RxJS 6 测试过的更简单且速度更快的方法:
range(1, 10000000)
.pipe(
filter(function(value, index) {
return index % 10 === 0;
}),
);
此代码比另一个答案中的 bufferCount
和 windowCount
方法快两倍:https://jsperf.com/observable-nth/1
这可能是因为 filter
运算符使用了一个简单的计数器,而不必保留最后 n
个元素的缓冲区。我认为当 n
更大或元素本身更大时,这会更快。使用 RxJS 6,您还可以轻松地将其变成您自己的自定义运算符:
const takeEveryNth = (n: number) => filter((value, index) => index % n === 0);
// usage: rxjs.range(1, 10000000).pipe(takeEveryNth(10));
也是官方文档中解释如何创建自定义运算符的代码:https://github.com/ReactiveX/rxjs/blob/6.2.2/doc/pipeable-operators.md
我正在使用 mousemove 事件创建一个可观察对象。
Observable.fromEvent(document, 'mousemove')
我需要每 10 个事件发出一次。我该怎么办?
我可以想到四种不同的方法:
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));
去抖动()
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();
扫描()
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));
但是,当使用 scan()
时,它将丢弃最后一个值 55
。
这是我用 RxJS 6 测试过的更简单且速度更快的方法:
range(1, 10000000)
.pipe(
filter(function(value, index) {
return index % 10 === 0;
}),
);
此代码比另一个答案中的 bufferCount
和 windowCount
方法快两倍:https://jsperf.com/observable-nth/1
这可能是因为 filter
运算符使用了一个简单的计数器,而不必保留最后 n
个元素的缓冲区。我认为当 n
更大或元素本身更大时,这会更快。使用 RxJS 6,您还可以轻松地将其变成您自己的自定义运算符:
const takeEveryNth = (n: number) => filter((value, index) => index % n === 0);
// usage: rxjs.range(1, 10000000).pipe(takeEveryNth(10));
也是官方文档中解释如何创建自定义运算符的代码:https://github.com/ReactiveX/rxjs/blob/6.2.2/doc/pipeable-operators.md