keydown和keyup事件RXJS之间的时间间隔

时间:2018-02-22 03:18:24

标签: javascript rxjs observable keydown

我希望在按下每个键的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拜托?

2 个答案:

答案 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}));
});

https://codepen.io/codepen0980/pen/dyNBwpd