繁体   English   中英

间隔 rxjs 不清除计时器

[英]interval rxjs not clearing timer

我有一个输入属性作为 setter:

   @Input() set moduleData(value: any) {
    this._moduleData = value;
    this.destroy$.next();
    this.destroy$.complete();
    this.startAttempt();
  } 



  startAttempt() {
    if (!this.isExamStarted()) {
      console.log("exam is not started");
      interval(1000).pipe(takeUntil(this.destroy$)).subscribe((res) => {
        if (
          this.canStartAssessment(this.moduleData.module_progress.start_time)
        ) {
          console.log("exam can be started now");
          this.getTimeRemainingInExam();
        } else {
          this.getTimer(
            this.moduleData.module_progress.start_time,
            false
          );
        }
      });
    } else {
      this.getTimeRemainingInExam();
    }
  }


ngOnDestroy(): void {
    console.log("componenet destroyef");
    this.destroy$.next();
    this.destroy$.complete();
  }

通过使用 takeUntil 运算符,我试图停止计时器。 我可以看到即使在组件被销毁后计时器仍然运行。 此外,当输入属性更改时,我可以看到它在 1 秒内被调用了两次。 对于 ex ,日志被打印两次,与先前值的输入一样多。 如何在再次开始间隔之前清除输入属性更改时的所有间隔?

您不必complete多播可观察对象destroy$

  1. 完成后,它们不会再次启动。
  2. 如果 observable 仅用于takeUntil ,则complete是多余的。 next就够了。 请参阅此处

尝试以下

@Input() set moduleData(value: any) {
  this._moduleData = value;
  this.destroy$.next(); // <-- `complete()` not required
  this.startAttempt();
}

...
ngOnDestroy(): void {
  console.log("component destroyed");
  this.destroy$.next(); // <-- `complete()` not required
}

.subscription必须被杀死。 你可以添加这个片段

interval(1000).pipe(takeUntil(this.destroy$)).subscribe((res) => {
  [...]
});

进入订阅数组并在 ngOnDestroy 生命周期钩子中取消订阅。

subscriptions: Subscription[] = [];

startAttempt() {
  [...]
  this.subscriptions.push(
    interval(1000).pipe(takeUntil(this.destroy$)).subscribe((res) => {
      [...]
    })
  )
  [...]
}

ngOnDestroy() {
  this.subscriptions.forEach(subscription => subscription.unsubscribe());
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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