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 + ', ';
      });

  }

}

キープレスカウンターの反応的および非反応的な方法を書き込もうとしました。関数 reactWay() を見てください

それは機能しますが、何か問題がある可能性があると思います。

私はそこでエクササイズをしました http://reactivex.io/learnrx/

たくさんのマッピングがありました。

時間イベントを、1 秒あたりに発生したキー イベントのシーケンスにマッピングする必要があったように感じます。しかし、どうすればそれらをマッピングできるのかわかりません。

何かのようなもの

// 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$ を使用する場合、2 番目にキーが押されていない場合に 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 の値を含むイベントを毎秒取得できません。1 秒間にいくつかのキーを押すと、押されたキーの数と 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 に答える