LoginSignup
4
4

More than 5 years have passed since last update.

初めてのRxJSをズンドコキヨシで

Last updated at Posted at 2016-03-15

※RxJSのドキュメント読んで理解する度に更新してくかも

便乗した。
https://twitter.com/kumiromilk/status/707437861881180160
http://qiita.com/shunsugai@github/items/971a15461de29563bf90

RxJSのドキュメントをみてやっつけでやった。RxJS触るの初めてなので多分よくわかってない。

パターンわかってるからbufferWithCount使えば簡単なのだけど、それよりも途中でSubscribeやめる方法がよくわからんかったのでcompletedみたいな変数を作ってしまい負けた気分。念のため無限ループにはしてない。(一回ミスってjsfiddle固まった)

var zundoko = ["ズン", "ドコ"];
var completed = false;
var zundokoSource = Rx.Observable.generate(
  0,
  function(i) { return i < 10000 && !completed; },
  function(i) { return i + 1;},
  function() { return zundoko[Math.floor(Math.random() * 2 )]}
);

zundokoSource.bufferWithCount(5, 1).subscribe(
  function(kotodama) {
    if(kotodama.join(",") === "ズン,ズン,ズン,ズン,ドコ") {
      console.log("キ・ヨ・シ!!");
      completed = true;
    }
  }
);

リズム版

ズンズンズンズンドコにはリズムがある。ただ単純にズンドコが並べば良いわけではなく、一つ目のズンと二つ目のズンの間は少し長めに、それ以降のズンとドコの間は短めの間がある。

その"間"自体もstreamのデータとして扱い、

ズン 1500ms ズン 750ms ズン 750ms ズン 750ms ドコ

となったときだけ「キ・ヨ・シ」するようにした。1500とか750は別に曲から正確に測ったわけではなく、だいたいである。

実際1500msなり750ms待つこともあり、なかなか「キ・ヨ・シ」を発動できない。

generateWithRelativeTimeを使ったversion

var zundoko = ["ズン", "ドコ"];
var intervals = [1500,750];
var dom = document.getElementById('zundoko');
var completed = false;
var zundokoSource = Rx.Observable.generateWithRelativeTime(
  0,
  function() { return !completed; },
  function() {},
  function() {
    var token = zundoko[Math.floor(Math.random() * 2 )];
    var p = document.createElement("p");
    p.innerHTML = token;
    dom.appendChild(p);
    return token;
  },
  function() {
    return intervals[Math.floor(Math.random() * 2)];
  }
).timeInterval();

var subscription = zundokoSource.bufferWithCount(5, 1).subscribe(
  function(buffer) {
    var zundoko = [];
    var intervals = [];
    buffer.forEach(function(word) {
      zundoko.push(word.value);
      // intervalは関数で指定しか時間ぴったりではなく
      // 数msecずれるので丸め込む
      intervals.push(Math.floor(word.interval / 10));
    })
    console.log(zundoko);
    console.log(intervals.slice(1));
    if(zundoko.join(",") === "ズン,ズン,ズン,ズン,ドコ" &&
      intervals.slice(1).join(",") === "150,75,75,75") {
      completed = true;
    }
  },
  function(error) {
    console.log("error");
  },
  function() {
    var p = document.createElement("p");
    p.innerHTML = "<strong>キ・ヨ・シ!!</srtong>";
    dom.appendChild(p);
  }
);

create使ったversion

var zundoko = ["ズン", "ドコ"];
var intervals = [1500,750];
var zundokoSource = Rx.Observable.create(function(observer) {
  var completed = false;
  function sing(interval) {
    var span = interval / 750;
    var zd = zundoko[Math.floor(Math.random() * 2)];
    var nextInterval = intervals[Math.floor(Math.random() * 2)];
    console.log(Array(span + 1).join("."));
    console.log(zd);
    observer.onNext(interval);
    observer.onNext(zd);
    if(!completed) {
      setTimeout(function(){ sing(nextInterval); }, nextInterval);
    }
  }
  sing(0);
  return function() {
    completed = true;
  };
});

var subscription = zundokoSource.bufferWithCount(9, 1).subscribe(
  function(kotodama) {
    if(kotodama.join(",") === "ズン,1500,ズン,750,ズン,750,ズン,750,ドコ") {
      console.log("キ・ヨ・シ!!");
      subscription.dispose();
    }
  }
);
4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4