2016-11-28 11 views
2

Ich verwende Rx, um eine Animationsuhr zu behalten. Jeder Animationsrahmen bildet ein Intervall-Tick auf die neuen Werte für dieses Häkchen ab.RxJS (5.0rc4): Einen Intervalltimer anhalten und fortsetzen

Angenommen, ich möchte die Animation anhalten. Der natürlichste Weg wäre, die Uhr rx irgendwie zu suspendieren und dann zu einem späteren Zeitpunkt wieder aufzunehmen.

Abbestellen, dann ist das Wiederbestellen keine natürliche Anpassung, weil diese Animationsuhr kalt beobachtbar ist. Ich möchte die Animation nicht neu starten, wenn sie fortgesetzt wird. Wenn ich eine Workaround-Methode einstelle, muss ich einen neuen Resume-Rx generieren, der alle exponierten APIs erheblich komplizierter macht.

Rückstau-Methoden nicht vielversprechend:

pause funktioniert nicht, weil ich fortsetzen will, wo ich aufgehört habe, nicht nach vorne springen. Mit anderen Worten, ich möchte keine Zecken abwerfen, solange es ausgeschaltet ist.

pausableBuffered funktioniert nicht, denn beim Fortsetzen werden alle angesammelten Ticks so schnell wie möglich geleert.

irgendeine Art eines virtuellen Zeit Scheduler vollständig Zeit zu stoppen und dann normale Zeit wieder aufnehmen könnte möglich sein (?)

Ich bin auf RxJS 5.0rc4, aber ich würde nicht wissen, wie das auf RxJS zu tun 4, entweder. Jeder Tipp für beide Versionen wäre willkommen.

Antwort

2

Verwenden Sie switchMap auf einem pauser Stream, um zwischen der ursprünglichen Quelle und zu wählen. Wenn Sie nicht möchten, dass der Timer springt, dann verwalten Sie ihn selbst (unter Verwendung der x Variable im Folgenden).

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

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

Der pauser-Stream sollte Booleans ausgeben.

Nicht getestet.

+0

Große Antwort. Der Umgang mit meinem eigenen Tick Counter mit einem Verschluss war der Schlüssel für mich. Dann kann ich das Intervall nach Belieben abonnieren und abbestellen, ohne mich darum sorgen zu müssen, dass ich den idx verliere. – masonk

+0

Eine knifflige Sache ist aufgetaucht. Ich habe jetzt eine pausierbare Uhr, und das Intervall wird während einer Pause nicht zurückgesetzt. Wenn dieses Observable jedoch mehrfach abonniert ist, z. Wenn ich clock.repeat() sage oder wenn ich diese Uhr mehreren Beobachtern übergebe, möchte ich, dass jede Instanz des Abonnements ihr eigenes i hat. Im Moment erhöhen alle Abonnements für die Uhr den gleichen Zähler. – masonk

0

Die Idee von torazaburo hat mich zu 95% gebracht. Der letzte Schritt bestand darin, dass ich die x-Schließung für jedes Abonnement einzigartig machen musste. Observable.create benötigte ich, um für jedes Abonnement eine Sperrung zu erstellen.

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()); 
    }); 
} 
Verwandte Themen