2016-11-28 1 views
2

Я использую Rx для сохранения часов анимации. Каждый анимационный кадр отображает интервал тика на новые значения для этого тика.RxJS (5.0rc4): пауза и возобновление интервала таймера

Предположим, я хочу приостановить анимацию. Наиболее естественным способом было бы как-то приостановить часы rx, а затем возобновить его позже.

Отказаться от подписки, после чего повторная подписка не является естественной, потому что эти часы анимации являются наблюдаемыми в холодном состоянии. Я не хочу перезапускать анимацию, когда они возобновляются. Если я перейду к методу обходного пути, мне придется создать новое резюме rx, значительно усложняющее все открытые API.

противодавления методы не кажутся многообещающими:

pause не работает, потому что я хочу возобновить, где я остановился, не прыгать вперед. Другими словами, я не хочу бросать тики, пока он выключен.

pausableBuffered не работает, потому что при возобновлении он сбрасывает все накопленные клещи как можно быстрее.

Использование своего рода виртуальный планировщик времени, чтобы полностью остановить время, а затем возобновить нормальное время может быть возможно (?)

Я на RxJS 5.0rc4, но я не знаю, как сделать это на RxJS 4, либо. Любые советы для любой версии будут оценены.

ответ

2

Используйте switchMap на потоке pauser, чтобы выбрать между исходным кодом и 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()); 
    }); 
}