1
/**
 * 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/

并且有很多映射。

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

就像是

// 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 总和?

更新

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

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。然后事件停止,直到我再次按下键。我需要修改什么以便每秒获得事件?

4

1 回答 1

3

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

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

请参阅以下链接:

于 2016-04-02T21:51:26.983 回答