RxJS v5 Pausable Observable Interval

时间:2017-09-20 00:57:37

标签: rxjs rxjs5

由于pausable运算符未在RxJS v5中实现,是否有更好的方法来创建可暂停的间隔?下面的代码可以工作,但是通过跟踪最后一个发射值作为偏移来实现。似乎应该有更好的方式...

const source = Rx.Observable.interval(100).share()
const offset = new Rx.BehaviorSubject(0)
let subscription;
let currentValue;

function start() {    
    subscription = source
        .subscribe(i => {
            currentValue = i + offset.value
      })
}



function pause() {
    source.take(1).subscribe(i => offset.next(i + offset.value))
    subscription.unsubscribe()
}

2 个答案:

答案 0 :(得分:1)

share()运算符为an alias for .publish().refCount()refCount()意味着当没有其他订阅者存在时,observable将自我清理。因为您从源代码取消订阅,它将自行清理,然后在subscribe d再次重新启动时重新启动。请将publish()connect()一起使用。这是代码:

const source = Observable.interval(100).publish();
source.connect();

// Start with false, change to true after 200ms, then false again
// after another 200ms
const pauser = Observable.timer(200)
  .mapTo(true)
  .concat(Observable.timer(200).mapTo(false))
  .startWith(false);

const pausable = pauser
  .switchMap(paused => (paused ? Observable.never() : source))
  .take(10);

pausable.subscribe(x => console.log(x));

有关正在运行的示例,请参阅此jsbin:http://jsbin.com/jomusiy/3/edit?js,console

答案 1 :(得分:0)

没有通用的方法来做到这一点。这取决于您暂停的具体含义以及您暂停的内容。 (你想停止发射,然后重新开始,你是否缓冲和消耗,或者你是否真的需要向上游添加延迟,但是否能及时保留上游值的分布?)

当上游特别是一个计时器时,我有办法以有效的方式执行此操作,就像在您的示例中一样。这是我自己的问题的答案。

RxJS (5.0rc4): Pause and resume an interval timer

这个有很大的优势,可以及时保留源的价值分布,但只是增加了延迟。

对于更一般的情况:

  1. 对于冷可观测量:switchnever和上游之间。暂停时,取消订阅上游。 skip您已经看到的,然后switchskip ed流。在取消暂停时,您必须保留已发出的值的数量,以便下次有人取消暂停时可以skip。你只需要记住你之前见过的人数。但是,每次取消都会导致冷可观察性从一开始就重放。在一般情况下,这可能非常效率低下。代码看起来像这样。 pauser这里是一个主题,你可以设置为true或false来暂停上游。

    function pausableCold(pauser, upstream) {
        var seen = 0;
        return pauser.switch(paused => {
            if (paused) {
                return Observable.never();
            }
            else {
                return upstream.skip(seen).do(() => seen++);
            }
        });
    }
    
  2. 对于热或冷可观测量,您可以使用缓冲。暂停时buffer暂停,然后在取消暂停时排空并连接到热的上游。 (这保留了所有的值,但它并没有及时保留它们的分布。另外,如果它可能很冷,你应该用publish加热上游。)

  3. 最有效的方式并不是Rx的一部分。你真正想要的是告诉来源停止发光,然后重新开始。您这样做的方式非常特定于源是什么以及源如何生成值。