我希望在按下每个键的keydown和keyup事件之间得到timeInterval
var keyDowns = Rx.Observable.fromEvent(document, "keydown");
var keyUps = Rx.Observable.fromEvent(document, "keyup");
var keyPresses = keyDowns.merge(keyUps)
//group by keycode, ie '87'= w
.groupBy(e => e.keyCode)
//map distinct keydowns and keyups - ideally, would want to get timeInterval after this
.map(group => group.distinctUntilChanged(null, e => e.type))
//flatten observable of key events observables
.mergeAll()
keyPresses.subscribe(function(e) {
console.log(e.type, e.key);
//console.log(e)
});
input: hold w, release w
output: keydown w
keyup w
我想将这些映射到像这样结构的对象
intervals = {'w-key': {
'press1': 1000ms
'press2': 1123ms
}
'd-key': {
'press1': 402ms
}
}
Haalp拜托?
答案 0 :(得分:0)
我认为withLatestFrom
是可以帮助您的运营商。这将为您提供非常接近您所寻找的东西:
const down = Rx.Observable.fromEvent(document, "keydown")
.distinctUntilKeyChanged("keyCode");
const up = Rx.Observable.fromEvent(document, "keyup");
up.withLatestFrom(down, (u, d) => ({
name: `${String.fromCharCode(d.keyCode)}-key`,
pressTime: u.timeStamp - d.timeStamp
}))
.groupBy(x => x.name)
.mergeMap(group => group.scan((acc, x) => {
acc[group.key].push(x.pressTime);
return acc;
}, {[group.key]: []}))
.scan((acc, x) => Object.assign(acc, x))
.subscribe(console.log);
答案 1 :(得分:0)
你怎么看这个?在 distinctUntilChanged 之后,我们使用 pairwise
将值与前一个值配对,然后使用新字段将它们映射回一个,即连续发射之间测量的 duration
时间。要获得第一个没有前驱的值,我们需要startWith
一个虚拟值 {timeStamp:undefined}
。
import { fromEvent, merge } from 'https://cdn.skypack.dev/rxjs@^6.6.7?min';
import {
groupBy,
map,
distinctUntilChanged,
mergeAll,
pairwise,
startWith } from 'https://cdn.skypack.dev/rxjs@^6.6.7/operators?min';
const keyPresses = merge(
fromEvent(window, 'keydown', {capture: true}),
fromEvent(window, 'keyup', {capture: true}),
).pipe(
groupBy(e => e.code),
map(group => group.pipe(
startWith({timeStamp:undefined}),
distinctUntilChanged(null, e=>e.type),
pairwise(),
map(([e0,e1])=>Object.assign(e1,{duration:e1.timeStamp-e0.timeStamp})))),
mergeAll(),
);
keyPresses.subscribe(e=> {
console.log(JSON.stringify({code:e.code, type:e.type, duration:e.duration}));
});