【问题标题】:RxJS (5.0rc4): Pause and resume an interval timerRxJS (5.0rc4):暂停和恢复间隔计时器
【发布时间】:2017-04-11 19:42:59
【问题描述】:

我正在使用 Rx 来保存动画时钟。每个动画帧,它都会将一个间隔刻度映射到该刻度的新值。

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

取消订阅然后重新订阅并不是一个自然的选择,因为这个动画时钟是一个冷的 observable。我不想在他们恢复时重新启动动画。如果我采用一种解决方法,我将不得不生成一个新的简历 rx,这会使所有暴露的 API 变得非常复杂。

背压方法似乎没有希望:

pause 不起作用,因为我想从中断的地方继续,而不是向前跳。换句话说,我不想在它关闭的时候滴滴答答。

pausableBuffered 不起作用,因为在恢复时,它将尽快耗尽所有累积的刻度。

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

我使用的是 RxJS 5.0rc4,但我也不知道如何在 RxJS 4 上执行此操作。任何版本的任何建议都将不胜感激。

【问题讨论】:

    标签: rxjs rxjs5


    【解决方案1】:

    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 流应该发出布尔值。

    未测试。

    【讨论】:

    • 很好的答案。用闭包处理我自己的刻度计数器是我的关键见解。然后就可以随意订阅和退订interval,不用担心丢失idx。
    • 出现了一件棘手的事情。我现在有一个可暂停的时钟,并且在暂停期间间隔不会重置。但是当该 observable 被订阅多次时,例如当我说clock.repeat(),或者当我把这个时钟传递给多个观察者时,我希望订阅的每个实例都有自己的i。现在所有对时钟的订阅都在增加同一个计数器。
    【解决方案2】:

    使用 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());
         });
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-06
      • 1970-01-01
      • 1970-01-01
      • 2021-02-16
      • 2021-08-31
      • 1970-01-01
      • 2020-06-04
      相关资源
      最近更新 更多