2016-11-28 64 views
2

我正在使用Rx保留动画时钟。每个动画帧都会将间隔记号映射到该记号的新值。RxJS(5.0rc4):暂停和恢复间隔计时器

假设我想暂停动画。最自然的方法是以某种方式暂停时钟rx,然后在稍后恢复。

退订然后重新订阅并非天作之合,因为这个动画时钟是冷观察到。我不想在恢复时重新开始动画。如果我采用一种解决方法,我将不得不生成一个新的简历rx,这极大地增加了所有暴露的API的复杂性。

背压方法似乎并不乐观:

pause不工作,因为我想继续我已关闭,而不是跳跃式前进。换句话说,我不想在关闭时滴滴答滴答。

pausableBuffered不起作用,因为在恢复,它会耗尽所有积蓄的蜱一样快,因为它可以。

使用某种虚拟时间调度完全停止的时间,然后恢复正常的时间可能是可能的(?)

我在RxJS 5.0rc4,但我不知道如何做到这一点的RxJS 4,要么。任何版本的任何意见,将不胜感激。

回答

2

pauser流上使用switchMap可在原始来源和Observable.never之间进行选择。如果您不希望计时器跳到前面,请自行管理(使用下面的x变量)。

function pausableInterval(ms, pauser) { 
    let x = 0; 
    const source = IntervalObservable.create(ms); 

    return pauser.switchMap(paused => paused ? Observable.never() : source.map(() => x++); 
} 

pauser流应该发出布尔值。

未经测试。

+0

伟大的答案。用闭包处理我自己的滴答柜台是我的关键洞察力。然后我可以随意订阅和取消订阅,而不用担心丢失idx。 – masonk

+0

有一个棘手的问题出现了。我现在有一个可以使用的时钟,并且间隔在暂停期间不会重置。但是当这个观察者被多次订阅时,例如当我说clock.repeat(),或者当我将这个时钟传递给多个观察者时,我希望订阅的每个实例都有它自己的i。现在所有的时钟订阅都增加了同一个计数器。 – masonk

0

使用torazaburo的想法让我有95%的感觉。最后一步是我需要x闭包对每个订阅都是唯一的。 Observable.create是我需要为每个订阅创建一个闭包。

pausableInterval(paused: Rx.Observable<boolean>): Rx.Observable<number> { 
    return Rx.Observable.create((obs: Rx.Observer<number>) => { 
     let i = 0; 
     let ticker = Rx.Observable.interval(1000/this.fps).map(() => i++) 

     let p = paused.switchMap(paused => paused ? Rx.Observable.never() : ticker); 
     return p.subscribe(val => obs.next(val), err => obs.error(err),() => obs.complete()); 
    }); 
}