web-dev-qa-db-ja.com

RXJSで監視可能な間隔を開始および停止するにはどうすればよいですか?

私は非常に単純なtimeIntervalを監視可能であり、サブスクライバを切断せずに送信を開始/停止したい(監視可能なステータスに関係なく座って待機する必要がある)。可能ですか、もしそうならどうすればよいですか?

var source = Rx.Observable
  .interval(500)
  .timeInterval()
  .map(function (x) { return x.value + ':' + x.interval; })
  .take(10);

  var subscription = source.subscribe(
  function (x) {
     $("#result").append('Next: ' + x + ' ');
  },
  function (err) {
    $("#result").append('Error: ' + err);
  },
  function () {
    $("#result").append('Completed');
  });

一般的なコメント:目に見える例のほとんどは、オブザーバブルとサブスクライバーを定義する方法を示しています。既存のオブジェクトの動作にどのように影響しますか?

13
Laurence Fass

停止/再開信号のソースに依存します。私が考えることができる最も簡単な方法は pausable operator を使用することです。これは、ドキュメントに記載されているように、ホットなオブザーバブルでよりよく機能します。したがって、次のサンプルコードでは、take(10)を削除し(一時停止可能な信号がpauserサブジェクトを通過するようになりました)、shareを追加して、オブザーバブルをホットなものに変換します。

var pauser = new Rx.Subject();
var source = Rx.Observable
  .interval(500)
  .timeInterval()
  .map(function (x) { return x.value + ':' + x.interval; })
  .share()
  .pausable(pauser);

var subscription = source.subscribe(
  function (x) {
     $("#result").append('Next: ' + x + ' ');
  },
  function (err) {
    $("#result").append('Error: ' + err);
  },
  function () {
    $("#result").append('Completed');
});

  // To begin the flow
pauser.onNext(true); // or source.resume();

// To pause the flow at any point
pauser.onNext(false);  // or source.pause();

以下は より洗練された例 で、10アイテムごとにソースを一時停止します。

// Helper functions
function emits ( who, who_ ) {return function ( x ) {
 who.innerHTML = [who.innerHTML, who_ + " emits " + JSON.stringify(x)].join("\n");
};}

var pauser = new Rx.Subject();
var source = Rx.Observable
  .interval(500)
  .timeInterval()
  .map(function (x) { return x.value + ':' + x.interval; })
  .share();
var pausableSource = source
  .pausable(pauser);

source
  .scan(function (acc, _){return acc+1}, 0)
  .map(function(counter){return !!(parseInt(counter/10) % 2)})
  .do(emits(ta_validation, 'scan'))
  .subscribe(pauser);

var subscription = pausableSource.subscribe(
  function (x) {
     $("#ta_result").append('Next: ' + x + ' ');
  },
  function (err) {
    $("#ta_result").append('Error: ' + err);
  },
  function () {
    $("#ta_result").append('Completed');
});

これで、2番目の質問に対する回答が得られます。与えられたオブザーバブルを関連するRxJSオペレーターと組み合わせて、ユースケースを実現します。これは私がここでやったことです。

16
user3743222

最もエレガントではありませんが、おそらく最もシンプルです。

  timeSubscription: Subscription
  timer: Observable<number>;
  time = 0;

toggle() {
if (!this.timer)
  this.timer = interval(500);

if (!this.timeSubscription || this.timeSubscription.closed)
  this.timeSubscription = this.timer.subscribe(tick => { // running
    console.log(this.time++);
  });
else
  this.timeSubscription.unsubscribe(); // not running 
}
0
EladTal