gpt4 book ai didi

javascript - 在 RxJ 中使用背压进行击键

转载 作者:行者123 更新时间:2023-11-28 06:12:55 26 4
gpt4 key购买 nike

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

到目前为止,我的代码正在运行:Hello 输出 ShiftLeftHELLO

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

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

(function (document) {
var textarea = document.querySelector("#input");
var keyUpStream = Rx.DOM.keyup(textarea);
var keyDownStream = Rx.DOM.keydown(textarea);
var keyStrokeStream = Rx.Observable.merge(keyDownStream, keyUpStream);

var keystroke = keyStrokeStream.filter((function() {
var keysPressed = {};
return function(e) {
var k = e.which;
if (e.type == 'keyup') {
delete keysPressed[k];
return true;
} else if (e.type == 'keydown') {
if (keysPressed[k]) {
return false;
} else {
keysPressed[k] = true;
return true;
}
}
};
})())
.distinctUntilChanged(function (e){
return e.type + e.which;
})
.timeInterval()
.bufferWithCount(2)
.zip(function (evts){
return {
"ts" : Date.now(),
"key": evts[0].value.code,
"evts" : evts,
"duration" : evts.reduce(function(a, b){
return b.value.timeStamp - a.value.timeStamp;
})
};
}).subscribe(function (e){
console.log(e);
document.querySelector("#output").textContent += e.key.replace("Key", '');
document.querySelector("#console").textContent += JSON.stringify(e);
});
})(document);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.all.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs-dom/7.0.3/rx.dom.js"></script>
<h1>KeyStroke</h1>
<textarea id="input" rows="5" cols="50"></textarea>
<div id="output"></div>
<div id="console"></div>

Streams

最佳答案

免责声明:这里是 Rxjs 菜鸟。

问题是您的代码期望在同一键按下键后再按下该键。当您快速打字时,您会遇到击键竞争条件,从而导致缓冲区中出现多次按键或按键。不是您在缓冲区中所期望的。

我修改了代码以利用您的过滤功能。该函数仅返回 keyup 事件,并保存相应的 keydown 笔划。这样,您就可以计算过滤函数内的间隔。我非常确定有一个仅使用 RxJS 函数的更优雅的解决方案,但由于您已经在过滤器函数中使用了状态,所以我对其进行了一些修改。

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

	(function (document) {
var textarea = document.querySelector("#input");
var keyUpStream = Rx.DOM.keyup(textarea);
var keyDownStream = Rx.DOM.keydown(textarea);
var keyStrokeStream = Rx.Observable.merge(keyDownStream, keyUpStream);


var keystroke = keyStrokeStream.filter((function() {
var keysPressed = {};

return function(e) {
var key = e.which;
var result;

if (e.type == 'keyup' && keysPressed.hasOwnProperty(key)) {
e.strokeInterval = Date.now() - keysPressed[key];
delete keysPressed[key];
return true;
} else if (e.type == 'keydown') {
if (!keysPressed.hasOwnProperty(key)) {
keysPressed[key] = Date.now();
}
return false;
}
return false;
};
})())
.map(function (evt){
return {
"ts" : Date.now(),
"key": evt.code,
"duration" : evt.strokeInterval
};
})
.subscribe(function (e){
console.log(e);
document.querySelector("#output").textContent += e.key.replace("Key", '');
document.querySelector("#console").textContent += JSON.stringify(e);
});
})(document);
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.all.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs-dom/7.0.3/rx.dom.js"></script>
<h1>KeyStroke</h1>
<textarea id="input" rows="5" cols="50"></textarea>
<div id="output"></div>
<div id="console"></div>

关于javascript - 在 RxJ 中使用背压进行击键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36224872/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com