首页 > 解决方案 > 暂停/恢复计时器 Observable

问题描述

我正在用 angular/rxjs6 构建一个简单的秒表,我可以启动计时器,但我不能暂停/恢复它。

  source: Observable<number>;
  subscribe: Subscription;

  start() {
    this.source = timer(0, 1000);
    this.subscribe = this.source
      .subscribe(number => {
        this.toSeconds = number % 60;
        this.toMinutes = Math.floor(number / 60);
        this.toHours = Math.floor(number / (60 * 60));

        this.seconds = (this.toSeconds < 10 ? '0' : '') + this.toSeconds;
        this.minutes = (this.toMinutes < 10 ? '0' : '') + this.toMinutes;
        this.hours = (this.toHours < 10 ? '0' : '') + this.toHours;
    });
  }

  pause() {
    this.subscribe.unsubscribe(); // not working
  }

经过大量搜索后,我发现我应该使用switchMap运算符来完成此操作,但我是 rxjs 的新手,不知道如何以正确的方式进行操作。

任何帮助将非常感激。

标签: angularangular6rxjs6

解决方案


我今天也遇到了同样的问题(使用 Angular 实现俄罗斯方块克隆时)。这是我最终得到的结果:

import { Subject, timer } from 'rxjs';

export class Timer {
  private timeElapsed = 0;
  private timer = null;
  private subscription = null;

  private readonly step: number;

  update = new Subject<number>();

  constructor(step: number) {
    this.timeElapsed = 0;
    this.step = step;
  }

  start() {
    this.timer = timer(this.step, this.step);
    this.subscription = this.timer.subscribe(() => {
      this.timeElapsed = this.timeElapsed + this.step;
      this.update.next(this.timeElapsed);
    });
  }

  pause() {
    if (this.timer) {
      this.subscription.unsubscribe();
      this.timer = null;
    } else {
      this.start();
    }
  }

  stop() {
    if (this.timer) {
      this.subscription.unsubscribe();
      this.timer = null;
    }
  }
}

在我的游戏服务中,我这样使用它:

  init() {
    this.timer = new Timer(50);
    this.timer.start();
    this.timer.update.subscribe(timeElapsed => {
      if (timeElapsed % 1000 === 0) {
        this.step(); // step() runs one game iteration
      }
    });
  }

  togglePause() {
    this.timer.pause();
  }

注意:我是 Angular/RxJS 的新手,所以我不确定上面的代码是否良好。但它有效。


推荐阅读