Javascript 在RxJs中使用按键的背压

Javascript 在RxJs中使用按键的背压,javascript,reactive-programming,rxjs,Javascript,Reactive Programming,Rxjs,我试图使用RxJS捕捉用户的击键,并为每个笔划生成一个结果对象,其中包含了键、笔划的持续时间(在keypup和keypdown事件之间的时间),以及先前笔划之间的间隔(使用timeInterval)。 有关概述,请参见下图 到目前为止,我的代码还在运行:HellooutputsShiftLeftHELLO 但当我写得更快时(我的意思是像往常一样),一切都会崩溃,World输出shiftleftleftold 您对在我的代码中实现、缓冲或其他东西来防止这种行为有什么建议吗 (功能(文档){ va

我试图使用RxJS捕捉用户的击键,并为每个笔划生成一个结果对象,其中包含了、笔划的持续时间(在
keypup
keypdown
事件之间的时间),以及先前笔划之间的间隔(使用
timeInterval
)。 有关概述,请参见下图

到目前为止,我的代码还在运行:
Hello
outputs
ShiftLeftHELLO

但当我写得更快时(我的意思是像往常一样),一切都会崩溃,
World
输出
shiftleftleftold

您对在我的代码中实现、缓冲或其他东西来防止这种行为有什么建议吗

(功能(文档){
var textarea=document.querySelector(“输入”);
var keyUpStream=Rx.DOM.keyup(textarea);
var keydown=Rx.DOM.keydown(textarea);
var keyStrokeStream=Rx.Observable.merge(键下游,键上游);
var keystroke=keyStrokeStream.filter((函数(){
var keysPressed={};
返回函数(e){
var k=e,其中;
如果(e.type=='keyup'){
删除按键[k];
返回true;
}否则如果(e.type=='keydown'){
如果(按[k]键){
返回false;
}否则{
按下键[k]=真;
返回true;
}
}
};
})())
.distinctUntilChanged(功能(e){
返回e.type+e.which;
})
.timeInterval()
.bufferWithCount(2)
.zip(函数(evts){
返回{
“ts”:Date.now(),
“键”:evts[0].value.code,
“EVT”:EVT,
“持续时间”:evts.减少(功能(a、b){
返回b.value.timeStamp-a.value.timeStamp;
})
};
}).订阅(功能(e){
控制台日志(e);
document.querySelector(“#output”).textContent+=e.key.replace(“key”,”);
document.querySelector(“#console”).textContent+=JSON.stringify(e);
});
})(文件)

击键

免责声明:这里是Rxjs noob

问题是,您的代码期望在同一个键的keydown之后从该键开始keydup。当您键入fast时,您在击键时有一个竞争条件,从而产生一个带有多个按键或上键的缓冲区。不是你期望的缓冲区

我已经修改了代码以利用你的过滤功能。该函数仅返回keyup事件,并保存相应的keydown笔划。这样,您就可以在filter函数中计算间隔。我很确定有一个更优雅的解决方案只使用RxJS函数,但是因为您已经在filter函数中使用了state,所以我对它做了一些修改

代码段现在显示了正确的输出。我认为它解决了您的问题,但这不是使用RxJS的好方法(正如我所说,我们将状态存储在filter函数中)

(功能(文档){
var textarea=document.querySelector(“输入”);
var keyUpStream=Rx.DOM.keyup(textarea);
var keydown=Rx.DOM.keydown(textarea);
var keyStrokeStream=Rx.Observable.merge(键下游,键上游);
var keystroke=keyStrokeStream.filter((函数(){
var keysPressed={};
返回函数(e){
var-key=e.which;
var结果;
if(e.type=='keyup'&&keysPressed.hasOwnProperty(键)){
e、 strokeInterval=Date.now()-keysPressed[key];
删除按下的键[键];
返回true;
}否则如果(e.type=='keydown'){
如果(!keysPressed.hasOwnProperty(键)){
keysPressed[key]=Date.now();
}
返回false;
}
返回false;
};
})())
.map(功能(evt){
返回{
“ts”:Date.now(),
“键”:evt.code,
“持续时间”:evt.strokeInterval
};
})
.订阅(功能(e){
控制台日志(e);
document.querySelector(“#output”).textContent+=e.key.replace(“key”,”);
document.querySelector(“#console”).textContent+=JSON.stringify(e);
});
})(文件)

击键

免责声明:这里是Rxjs noob

问题是,您的代码期望在同一个键的keydown之后从该键开始keydup。当您键入fast时,您在击键时有一个竞争条件,从而产生一个带有多个按键或上键的缓冲区。不是你期望的缓冲区

我已经修改了代码以利用你的过滤功能。该函数仅返回keyup事件,并保存相应的keydown笔划。这样,您就可以在filter函数中计算间隔。我很确定有一个更优雅的解决方案只使用RxJS函数,但是因为您已经在filter函数中使用了state,所以我对它做了一些修改

代码段现在显示了正确的输出。我认为它解决了您的问题,但这不是使用RxJS的好方法(正如我所说,我们将状态存储在filter函数中)

(功能(文档){
var textarea=document.querySelector(“输入”);
var keyUpStream=Rx.DOM.keyup(textarea);
var keydown=Rx.DOM.keydown(textarea);
var keyStrokeStream=Rx.Observable.merge(键下游,键上游);
var keystroke=keyStrokeStream.filter((函数(){
var keysPressed={};
返回函数(e){
var-key=e.which;
var结果;
if(e.type=='keyup'&&keysPressed.hasOwnProperty(键)){
e、 strokeInterval=Date.now()-keysPressed[key];
删除按下的键[键];
返回true;
}否则如果(e.type=='keydown'){
如果(!keysPressed.hasOwnProperty(键)){
keysPressed[key]=Date.now();
}
返回false;
}
返回false;
};
})())
.map(功能(evt){
返回{
“ts”:Date.now(),
“键”:evt.code,
“持续时间”:evt.strokeInterval
};
})
.订阅(功能(e){
控制台日志(e);
document.querySelector(“输出”).textContent