使任何Observable行为像ReplaySubject

时间:2016-03-28 21:08:45

标签: javascript rxjs

我一直试图让我的流只用一点运气重播最新的价值。基本上,我在一个我不能手动replaySubject(1)的地方有一个.onNext。我想做的就是把它拿出来,把它映射到其他东西,然后添加一个初始值。

我的第一直觉如下:

var testInStream = new Rx.ReplaySubject(1);
var testOutStream = testInStream.startWith(-1);

testInStream.onNext(0);

setTimeout(function(){
       testOutStream.subscribe(function(x){ 
       console.log("stream:", x);
   });
}, 1000);

打印

stream: test -1
stream: test 0

但是,我想找到一种只打印stream: test 0的方法。我能想出的最接近的是

var testInStream = new Rx.ReplaySubject(1);
var testOutStream = testInStream.startWith(-1);

testInStream.onNext(0);

var wrapperSubject = new Rx.ReplaySubject(1);
testOutStream.subscribe(function(new_val){ wrapperSubject.onNext(new_val) });

setTimeout(function(){
  wrapperSubject.subscribe(function(x){ 
    console.log("stream:", x);
  });
}, 1000);

返回

stream: test 0

这就是我想要的。但是,我宁愿不创建一个中间的replaySubject,我宁愿只调用testOutStream.latest()testOutStream.replay(1)这样的东西,但我还没有让它们中的任何一个起作用。

我们非常感谢您的帮助,这里有JS Bin我的例子。

2 个答案:

答案 0 :(得分:0)

您可以使用shareReplay(1),示例代码为here

var validation$ = Rx.Observable
 .fromEvent(document.getElementById('validation'), 'click')
 .map(function(_, index){
   return ++counter;
   })
 .do(emits(ta_validation, 'index'))
 .shareReplay(1)

validation$.subscribe(function(){})

setTimeout(function() {
  validation$
  .do(emits(ta_result, 'second subscription'))
  .subscribe(function(){    });}, 3000)

我天真地尝试了replay(1)connect,但奇怪的是整个流值被重播。最好是使用shareReplay

另请注意,以下操作符可能会有所帮助,具体取决于您对“最新”操作的确切要求。值:

答案 1 :(得分:0)

有一个更清洁的解决方案。鲜为人知的秘密是观察者(例如Subject)可以作为订阅处理程序传递。所以完成这项工作的代码是:

var testInStream = new Rx.ReplaySubject(1);
// var testOutStream = testInStream.startWith(-1);

var testOutStream = new Rx.ReplaySubject(1);
testInStream.startWith(-1).subscribe(testOutStream);

testInStream.onNext(0);

setTimeout(function(){
       testOutStream.subscribe(function(x){ 
       console.log("stream:", x);
   });
}, 1000);

请参阅this jsbin