2016-11-28 4 views
2

私はRxを使ってアニメーションクロックを保持しています。アニメーションフレームごとに、インターバルティックをそのティックの新しい値にマッピングします。RxJS(5.0rc4):インターバルタイマを一時停止してから再開

アニメーションを一時停止したいとします。最も自然な方法は、何とかクロックrxを中断し、後でそれを再開することです。

このサブスクリプションを購読解除すると、このアニメーション時計は寒い観察可能なので、resubscribeは自然なフィットにはなりません。再開時にアニメーションを再開したくありません。私が回避策をとるために行くと、私は新しいレジューム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

1つのトリッキーなことが起こった。一時停止中にクロックが一時停止していて、間隔がリセットされません。しかし、その観測値が複数回にサブスクライブされると、例えば、私が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()); 
    }); 
} 
関連する問題