首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在RxJs中使用背压击键

在RxJs中使用背压击键
EN

Stack Overflow用户
提问于 2016-03-25 17:31:35
回答 1查看 185关注 0票数 1

我试图使用RxJS捕捉用户的击键,并为每一笔生成一个结果对象,该对象包含、笔画的工期( keyupkeydown事件之间的时间)和以前笔画之间的间隔(使用timeInterval)。有关概述,请参见下面的图像。

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

但是,当我编写更快的时(我的意思是),一切都会崩溃,World输出ShiftLeftShiftLeftOLD

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

代码语言:javascript
复制
(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);
代码语言:javascript
复制
<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>

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-29 11:06:13

免责声明: Rxjs noob在这里。

问题是,您的代码期望从一个键到一个键,然后再从那个键中按下一个键。键入“快”时,在击键时会出现争用条件,从而产生带有多个按键或密钥的缓冲区。不是你在缓冲区里期望的那样。

我已经修改了代码以利用您的过滤器功能。该函数只返回keyup事件,并保存相应的按键笔画。这样,就可以计算过滤器函数中的间隔。我确信有一个更优雅的解决方案,只使用RxJS函数,但是由于您已经在过滤器函数中使用了状态,所以我对它做了一些修改。

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

代码语言:javascript
复制
	(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);
代码语言:javascript
复制
<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>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36224872

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档