我必须在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();
}
}
所以我在这里有两个问题:
1)使用Observable的计时器是否不错,还是应该使用setInterval()方法,还是两者具有相同的性能?
2)如您所见,每次计时器计时,我必须做两次计算:
首先:我必须将秒转换为分钟。
第二:我必须检查计时器是否已达到时间限制,如果是,则要取消订阅计时器。
我的两个问题都与使计时器尽可能准确有关。 (尽可能接近实时)。正如您所注意到的,我给了tim间隔990毫秒而不是1000毫秒,以弥补由于tickerFunc()主体内部的计算而发生的时间损失。
最佳答案
严格来说,在给定的时间间隔后执行一个功能,一个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());
注意,我使用了take运算符仅具有所需数量的事件,并在完成的回调中调用finishTest。
我使用了RxJs 5.5中提供的新的lettable运算符,其代码将与旧版本非常相似。
您还可以删除订阅并在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),
);
您可以使用map将值转换为所需的值(注意,我在那里添加了+ 60以确保它们正在增加,您可以添加timeNow中具有的任何初始值),然后在模板中使用异步管道来呈现此值。
tap方法(以前称为do)将检查它是否是发出的最后一个项目,如果是,则调用finishTest。
关于angular - setInterval vs Observable的timer方法,最好创建计时器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47374599/