【问题标题】:how to reset timer observable如何重置可观察的计时器
【发布时间】:2020-07-07 21:26:44
【问题描述】:

我有一个计时器(它可以触发 observable)——我将它放在服务构造函数中。假设它每 10 秒获取一次数据(代码是手动复制的,而不是复制粘贴,请见谅):

@Injectable({
  provideIn: "root",
})
export class myService {
  isGetFullData: boolean;
  subscription: Subscription;
  myDataSubject = new Subject<any>;
  myDataSubjectChanged : Observable<any> = this.myDataSubject.asObservable(); 

  constructor(private httpClient: HttpClient) {
    this.subscription = timer(0, 10000)
      .pipe(switchMap(() => this.getData()))
      .subscribe();
  }

  getData(): Observable<any> {
    return this.httpClient.get<any>(url).
      pipe
      (
        tap(res => 
        {
           this.myDataSubject.next(res); 
        }), 
        catchError(error => throwError(error))
      );
    /* The data depends on the isGetFullData variable. */
  }
}

服务被注入到需要其数据的组件中。 现在 - 我有一个不同的组件可能会改变 isGetFullData 变量。 当这个变量改变值时,我不想立即执行 getData(),结果 - 计时器再次开始他的周期,从那个点开始。

这是更改服务的 isGetFullData 值的组件:

export class myComponent {
  constructor(private mySrv: myService) {}

  ToggleGetDataStatus() {
    this.mySrv.isGetFullData = !this.mySrv.isGetFullData;
  }
}

【问题讨论】:

  • 你没有使用定时器发出的值,那么the timer starts his cycles again是什么意思
  • @RafiHenig - 我正在使用它,我已将其添加到代码中 - 我正在设置 myDataSubject 并在相关组件中监听 myDataSubjectChanged 可观察对象。
  • 是的,但你没有使用数值,所以为什么要重置计时器
  • @RafiHenig - 我想将第一个请求设为“0 时间”,然后每 10 秒一次,尽管 - 我倾向于承认 - 立即执行 api 调用并让计时器继续。这可能会导致 API 调用和 1 或 2 或 3 秒后由计时器触发的另一个调用。

标签: angular timer rxjs


【解决方案1】:

下面的修改怎么样:

  private readonly getFullDataChanged = new Subject<void>();
  public toggleFullData = () => this.getFullDataChanged.next()

  constructor(private httpClient: HttpClient) {
    this.getFullDataChanged 
      .pipe(
        startWith(null),
        switchMapTo(timer(0, 10000)),
        mergeMap(this.getData)
      )
      .subscribe();
  }

在您的组件中:

ToggleGetDataStatus() {
  this.mySrv.toggleFullData()
}

【讨论】:

  • 为什么需要做一个 BehaviorSubject 而不仅仅是一个 Subject 作为触发器?
  • @Jonathan Stellwag 我使用BehaviorSubjext 所以我可以立即获得第一个值
  • 你也可以使用 startWith。
【解决方案2】:

找到了怎么做 - 我需要“重新启动”计时器,取消订阅计时器订阅,然后重新设置它。在服务中:

restartTimer()
{
  this.subscription.unsubscribe();
  this.subscription = timer(0, 10000)
  .pipe(switchMap(() => this.getData()))
  .subscribe();
}

当 isGetFullData 发生变化时(我们可以在其主题上使用 observable),执行 restartTimer

【讨论】:

  • 我不建议您订阅/取消订阅重置值或在 rxjs 中进行其他操作。只要您需要来自可观察对象的信息,就应该打开订阅。尝试检查上述答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-28
  • 2015-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
相关资源
最近更新 更多