2016-11-28 110 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()); 
    }); 
}