如何重新启动rxjs间隔?

Lez*_*rte 8 rxjs

我创建了一个类,它Observable使用interval运算符设置了一个可暂停的 RxJS :

export class RepeatingServiceCall<T> {
  private paused = false;
  private observable: Observable<T>;
  constructor(serviceCall: () => Observable<T>, delay: number) {
    this.observable = interval(delay).pipe(flatMap(() => (!this.paused ? serviceCall() : NEVER)));
  }
  setPaused(paused: boolean) {
    this.paused = paused;
  }
  getObservable() {
    return observable;
  }
}
Run Code Online (Sandbox Code Playgroud)

这似乎工作正常,但我试图解决的问题是我希望计时器在取消暂停时重置。所以,假设interval时间是最后一次interval发出后 10 秒和 5 秒,setPaused(false)被调用。在那种情况下,我希望它立即发出,然后重新启动计时器。

添加这样的东西会很容易吗?

s.a*_*lem 21

如果您使用timer代替interval,并将初始延迟设置为0,那么您的间隔将立即触发。

您可以使用takeUntiloperator 来防止间隔始终运行,并且repeatWhenoperator 可以随时重新启动它:

import { Observable, Subject, timer } from 'rxjs';
import { repeatWhen, switchMap, takeUntil } from 'rxjs/operators';

export class RepeatingServiceCall<T> {
  readonly observable$: Observable<T>;
  private readonly _stop = new Subject<void>();
  private readonly _start = new Subject<void>();

  constructor(serviceCall: () => Observable<T>, delay: number) {
    this.observable$ = timer(0, delay)
      .pipe(
        switchMap(() => serviceCall()),
        takeUntil(this._stop),
        repeatWhen(() => this._start)
      );
  }
  start(): void {
    this._start.next();
  }
  stop(): void {
    this._stop.next();
  }
}
Run Code Online (Sandbox Code Playgroud)

这是一个有效的StackBlitz 示例

PS: getter 和 setter 在打字稿中的工作方式不同。所以你不需要经典的 getter 概念,你可以只制作属性publicreadonly