我正在使用Angular 6创建HTML记分板。经过一些尝试,我想出了以下解决方案:
import {EventEmitter, Output} from '@angular/core';
export class Timer{
private delay: number = 0;
private interval: number = 0;
private directionUp: boolean = true;
time: number = 0;
private lastTick: number;
private intHold: number;
private toHold: number;
private expectedTick: number;
@Output() timeUp = new EventEmitter();
constructor(_interval: number, countDown: boolean,_startTime: number ){
this.interval = _interval;
if (_startTime)
this.time = _startTime;
if(countDown){
this.directionUp = false;
}
}
private timeRunner(){
this.lastTick = Date.now(); //is it ok to use Date.now()?
if (this.directionUp) {
this.time++;
} else {
if (this.time > 0){
this.time--;
} else {
window.clearInterval(this.intHold);
this.intHold=null;
this.timeUp.emit();
}
}
}
run(){
if (!this.toHold && !this.intHold) {
var self = this;
if (this.delay > 0) { //on stop and start I use the difference from the "expected" delay
this.expectedTick= Date.now() + this.delay;
this.toHold=window.setTimeout(function(){
self.timeRunner();
self.intHold=window.setInterval(function(){self.timeRunner();}, self.interval);
}, this.delay);
} else {
self.timeRunner();
self.intHold=window.setInterval(function(){self.timeRunner();}, self.interval);
}
}
}
stop (stopTime: number) {
//stopTime is needed because it may run over WebSocket
window.clearInterval(this.intHold);
window.clearTimeout(this.toHold);
this.intHold = null;
this.toHold = null;
if (!this.expectedTick || stopTime > this.expectedTick) {
this.delay=this.interval-(stopTime-this.lastTick);
} else {
//time didn't tick, so I calculate new delay
this.delay = this.expectedTick-stopTime;
}
}
reset (_startTime: number) {
this.time = _startTime;
}
}
我对Date.now()
的使用以及对重新启动时重新计算延迟的方式有疑问。 expectedTick
的计算是否正确,或者从长远来看效率低下?计时器将是我项目的核心要素,因此我需要它非常可靠。