setInterval vs Observable的timer方法,最好创建计时器

Him*_*tal 5 timer observable angular

我必须在Angular中创建一个计时器,目前我正在通过Observable进行如下操作:

  timer: Observable<any> = Observable.timer(0, 990);
  timerSubscription: Subscription;

  this.timerSubscription = this.timer.subscribe((value) => {
    this.tickerFunc();
  }); // inside ngOnInit

  tickerFunc () {
    this.timeNow++;

    this.timeNowInMinutes = Math.floor(this.timeNow / 60);

    if (this.timeNow >= this.TimeLimit) {
      this.finishtest();
    }
  }
Run Code Online (Sandbox Code Playgroud)

所以我在这里有两个问题:

1)使用Observable的计时器是否不错,还是应该使用setInterval()方法,还是两者具有相同的性能?

2)如您所见,每次计时器计时时,我都必须进行两次计算:

第一:我必须将秒转换为分钟。

第二:我必须检查计时器是否已达到时间限制,如果是,请取消计时器的订阅。

我的两个问题都与使计时器尽可能准确有关。(尽可能接近实时)。正如您所注意到的,我给了tim间隔990毫秒而不是1000毫秒,以弥补由于tickerFunc()主体内部的计算而发生的时间损失。

Adr*_*ciu 3

严格来说,对于在给定时间间隔后执行函数,Observable 可能有点矫枉过正,但由于您需要操纵该时间间隔,因此它应该是一个很好的用例:

import { timer } from 'rxjs/observable/timer';
import { take } from 'rxjs/operators';

timer(0, 990).pipe(
    take(this.timeLimit),
)
.subscribe((v) => this.timeNowInMinutes = Math.floor(v / 60),
           (err) => console.log(err),
           () => this.finishTest());
Run Code Online (Sandbox Code Playgroud)

请注意,我使用 take 运算符仅获取所需数量的事件,并在已完成的回调中调用 finishTest。

我使用了 RxJs 5.5 中提供的新的可出租运算符,代码与旧版本非常相似。

您还可以删除订阅并在 Angular 中使用异步管道,但在这种情况下,对 finishTest 的完成调用有点隐藏:

const $timerStream = timer(0, 990).pipe(
    take(this.timeLimit),
    map(v => Math.floor(v + 60 / 60)),
    tap(v => v === this.timeLimit ? this.finishTest() : undefined),
);
Run Code Online (Sandbox Code Playgroud)

您可以使用 map 将值转换为您需要的值(请注意,我在那里添加了 + 60 以确保它们在增加,您可以添加 timeNow 中的任何初始值),然后使用模板中的异步管道渲染这个值。tap 方法(以前称为 do)将检查它是否是最后发出的项目,如果是,则调用 finishTest。