重置Observable.timer()

时间:2018-08-07 12:10:31

标签: angular rxjs

我已经尝试制作计时器,但是有一个问题,我不知道如何重置(刷新)计时器。

startTimer() {
Observable.timer(this.countDownDuration, 1000)
        .map(i => this.countDownDuration - i)
        .take(this.countDownDuration + 1)
        .subscribe(i => {
          this.countDown = i;
          console.log(this.countDown);
        });
}

resetTimer() {
  must stop previous timer and start new 
}

任何建议

4 个答案:

答案 0 :(得分:2)

const s = new BehaviorSubject(null);

s.switchMap(() => Observable.timer(this.countDownDuration, 1000))
  .map(...)
  ...
  .subscribe(...);

resetTimer() {
  s.next();
}

答案 1 :(得分:0)

我找到了另一种方法。 在我的示例中,我必须使用take。 我知道如何重置throwSwitchMap。 但这对我不好。 可能这不是一个好决定。

status;

startTimer() {
this.status = Observable.timer(this.countDownDuration, 1000)
        .map(i => this.countDownDuration - i)
        .take(this.countDownDuration + 1)
        .subscribe(i => {
          this.countDown = i;
          console.log(this.countDown);
        });
}

resetTimer() {
  this.status.unsubscribe(); 
  this.startTimer();
}

答案 2 :(得分:0)

马丁的答案(https://stackoverflow.com/a/51726532/3024975)是正确的,但我不喜欢订阅BehaviorBehicle。因此,这是另一种选择:

我们需要一种信号化Observable来重新启动自身。这是Subject

的好用例
const signal = new Subject();

Observable.defer(() => Observable.timer(this.countDownDuration, 1000))
  .takeUntil(signal)
  .repeat()
  .map(....)
  .subscribe(...);

resetTimer() {
  signal.next();
}

我使用takeUntil停止可观察对象,并立即使用repeat重复该操作。 defer用于创建具有新的this.countDownDuration值的计时器(我希望它会改变)。

答案 3 :(得分:0)

这是另一种解决方案:

  recording$ = new BehaviorSubject(false);
  stopWatch$: Observable<number>;

  ngOnInit() {

    this.stopWatch$ = this.recording$.pipe(
      switchMap(r => r ? timer(0, 10) : never()),
      share()
    );

  }

  start() {
    this.recording$.next(true);
  }

  stop() {
    this.recording$.next(false);
  }