Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
4
Help us understand the problem. What is going on with this article?

More than 5 years have passed since last update.

@halhide

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

※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
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
4
Help us understand the problem. What is going on with this article?