【问题标题】:Counting keypresses per second with angular 2 Rxjs使用角度 2 Rxjs 计算每秒的按键次数
【发布时间】:2016-04-02 21:07:10
【问题描述】:
/**
 * Created by darius on 02/04/16.
 */
import { Component } from 'angular2/core';
import { Observable } from 'rxjs/Rx';


@Component({
  styles: [ require('../../style.css') ],
  selector: 'keypresses-per-second',

  template: `

    <div class="block">

      <input  type="text" (keypress)="onKeypress($event)">

      {{keypresses}} <br>
      <input type="text" (keypress)="onKeypressReact($event)">
      {{keypressesReactive}}
    </div>
  `
})

export class KeypressesPerSecond {

  ngOnInit() {

    this.nonReactive();

    this.reactiveWay();
  }

  // not reactive
  keypresses = '';
  counter = 0;
  secondsPassed = 0;

  nonReactive(){

    var self = this;

    var int = setInterval(function(){

      console.log(self.counter, 'counter in non reactive')
      self.keypresses += self.counter + ', ';
      self.counter = 0;
      self.secondsPassed++
      if (self.secondsPassed > 30) {
        clearInterval(int);
      }
    }, 1000);
  }

  onKeypress($event){
    console.log($event.keyCode);
    this.counter++;
  }
  // end not reactive

  onKeypressReact() {}

  keypressesReactive = '';
  reactiveCount = 0;

  reactiveWay() {

    console.log('reactive way')

    const keypressObservable$ = Observable.create(observer => {

      // from template
      this.onKeypressReact = () => { observer.next('press'); };
    });


    keypressObservable$.subscribe(function(event) {
      self.reactiveCount++;
    });

    var self = this;

    var timer$ = Observable.create(function(observer){

      // is subscribed to this observable
      var subscribed = true;
      var int = setInterval(function() {

        if (subscribed) {
          observer.next(self.reactiveCount);
          self.reactiveCount = 0;
        }

        if (self.secondsPassed > 30) {
          observer.complete();
          clearInterval(int)
        }

      }, 1000);

    })


    timer$.subscribe(
      function (x) {
        console.log('Nextzz: %s', x);
        self.keypressesReactive += x + ', ';
      });

  }

}

我尝试编写按键计数器的反应式和非反应式方式。 看看函数reactiveWay()

它有效,但我认为可能有问题。

我在那里做过excersizes http://reactivex.io/learnrx/

还有很多映射。

感觉就像我必须将时间事件映射到每秒发生的关键事件序列。 但不明白我怎么能映射这些。

类似

// doing this way we could removed some code from timer$, we just need to get an event
var kps$ = timer$.concatMap(function(time) {

  var sum = keypressObservable$.takeUntil(timer$)
    .reduce(function (acc, cur) {
      return acc + cur;
    })

  console.log('sum', sum);

  return sum;
})

// this works, counts the keypresses, but only when pressing at least 1. 
kps$.subscribe(
  function (x) {
    console.log('kps next', x);
    self.keypressesReactive += x + ', ';
  });

如果我使用 kps$,我如何强制 kps$ 在第二个没有按键完成时发出 0 sum?

更新

根据答案,我已经做到了。

var source = Observable.fromEvent(document.body, 'keypress');

var delayedSource = source.delay(1000);


var obs = source

  .buffer(delayedSource)


  .map((clickBuffer) => {
    return clickBuffer.length;
  })

但是当我订阅 obs 时,我每秒都没有收到包含 0 值的事件。当我在一秒钟内按下一些键时,我会得到按下的键数和另一个事件 0。然后事件停止,直到我再次按下键。 我需要修改什么以便每秒获得事件?

【问题讨论】:

    标签: angular rxjs5


    【解决方案1】:

    我认为您可以利用缓冲区运算符。它允许缓冲事件并在一段时间后发送它们。然后,您可以将此事件列表映射到其长度。

    var source = Observable.fromEvent(document.body, 'keyup');
    
    var obs = source
         .bufferTime(1000).map((clickBuffer) => {
           return clickBuffer.length;
         });
    
    obs.subscribe((num) => {
      // Get the number of pressed keys per second
    });
    

    查看这些链接:

    【讨论】:

    • 对我不起作用,至少在 RxJs 5 中 - 出现错误:错误:(161, 15) TS2345: '() => Observable' 类型的参数不可分配给'Observable' 类型的参数。类型“() => Observable”中缺少属性“_isScalar”。
    • 发现了如何修复错误 - 将延迟源传递给缓冲区函数。但它仍然不能像我想要的那样工作
    • 你是对的。您应该使用 bufferTime 运算符。我相应地更新了我的答案......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    • 2013-07-29
    相关资源
    最近更新 更多