简体   繁体   中英

Reset Observable.timer()

I've try to make my Timer but , have got one problem I couldn't understand how to reset(refresh) my timer.

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 
}

Any suggestions

const s = new BehaviorSubject(null);

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

resetTimer() {
  s.next();
}

I found some another way for this. And in my example I must use take. I know how to reset throw switchMap. But it's not good for me. May be it'is not good decision.

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

The martin's answer ( https://stackoverflow.com/a/51726532/3024975 ) is correct, but I don't like subscribing the BehaviorSubject. So this is an alternative:

We need a way to sinal the Observable to restart itself. This is a good use case for Subject

const signal = new Subject();

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

resetTimer() {
  signal.next();
}

I use takeUntil to stop the Observable and immediately repeat it using repeat . defer is used to create timer with new this.countDownDuration value (I expect it's going to change).

Here's another solution:

  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);
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM