[TypeScript] 基于本地时间的定时器
2020-05-01 本文已影响0人
码上说
计时器
点击获取源码。
API
- constructor : 构造器
/**
* 定时器构造器
* @summary 构造时使用秒为单位,实际会转换成毫秒
* @param callback 定时器回调
* @param call_interval 定时器调用间隔
* @param stop_after 停止时间
* @param call_after 延迟时间
*/
constructor(
callback: Function,
call_interval: number,
stop_after: number,
call_after?: number,
stop_callback?: Function
)
- start : 启动定时器
- pause : 暂停定时器
- resume : 恢复定时器
- stop : 停止计时器
- restart : 重启定时器
- elapse : 当前计时
- rest : 剩余计时
用法
import Timer from "./Timer"
new Timer(
function callback(timer: Timer) {
console.log(timer.elapse / 1000 + "s");
},
1,
10,
0,
function onStop(timer: Timer) {
timer.restart();
}
).start();
源码展示
IdGenerator.ts
/**
* 运行时Id生成器
*/
class __IdGenerator {
private id: number = 0;
private category: string = "";
/**
* Id生成器构造器
* @param category 类型
*/
constructor(category: string) {
this.category = category || "default";
this.id = 0 | (Math.random() * 998);
}
/**
* 获取新的id
*/
next() {
return this.category + "." + ++this.id;
}
}
export namespace IdGenerator {
export let timer = new __IdGenerator("timer");
}
Timer.ts
import { IdGenerator } from "./IdGenerator";
/**
* 基于本地时间的定时器
*/
export default class Timer {
//定时器标识
public category: string;
//已经计时
private time_elapse: number;
//心跳计时器
private tick_counter: any;
//记录开始时间
private start_at: number;
//毫秒后调用
private call_after: number;
//毫秒后暂停
private stop_after: number;
//计时间隔
private call_interval: number;
//计时回调
private callback: Function;
//计时回调
private stop_callback: Function;
//运行状态
private state: "ready" | "running" | "paused" | "stopped";
/**
* 定时器构造器
* @summary 构造时使用秒为单位,实际会转换成毫秒
* @param callback 定时器回调
* @param call_interval 定时器调用间隔(s)
* @param stop_after 停止时间(s)
* @param call_after 延迟时间(s)
*/
constructor(
callback: Function,
call_interval: number,
stop_after: number,
call_after?: number,
stop_callback?: Function
) {
this.category = IdGenerator.timer.next();
this.callback = callback;
this.call_interval = call_interval * 1000;
this.stop_after = stop_after * 1000;
this.call_after = (call_after || 0) * 1000;
this.stop_callback = stop_callback || idleHandler;
this.reset();
}
/**
* 重启定时器
*/
restart() {
this.stop();
this.reset();
this.start();
}
/**
* 启动定时器
*/
start() {
if (this.tick_counter !== null) {
return;
}
let time_out_id = setTimeout(() => {
clearTimeout(time_out_id);
this.start_at = this.now();
this.state = "running";
this.dump();
this.tick_counter = setInterval(() => {
if (this.state === "running") {
this.callback(this);
if (this.elapse >= this.stop_after) {
this.stop();
this.stop_callback(this);
}
}
}, this.call_interval);
}, this.call_after);
}
/**
* 当前时间
*/
private now(): number {
return Date.now().valueOf();
}
/**
* 获得当前计时(ms)
* @returns number 当前计时(ms)
*/
get elapse(): number {
let elapse = 0;
if (this.state === "running") {
elapse = this.time_elapse + this.now() - this.start_at;
} else {
elapse = this.time_elapse;
}
return Math.min(elapse, this.stop_after);
}
/**
* 获得剩余计时(ms)
* @returns number 剩余计时(ms)
*/
get rest(): number {
return this.stop_after - this.elapse;
}
/**
* 重置定时器
*/
private reset() {
if (this.tick_counter !== null) {
clearInterval(this.tick_counter);
}
this.state = "ready";
this.start_at = this.now();
this.time_elapse = 0;
this.tick_counter = null;
}
/**
* 暂停定时器
*/
pause() {
if (this.state === "running") {
this.time_elapse += this.now() - this.start_at;
this.state = "paused";
this.dump();
}
}
/**
* 恢复定时器
*/
resume() {
if (this.state === "paused") {
this.start_at = this.now();
this.state = "running";
this.dump();
}
}
/**
* 停止计时器
*/
stop() {
if (this.state !== "stopped") {
clearInterval(this.tick_counter);
this.tick_counter = null;
this.time_elapse += this.now() - this.start_at;
this.time_elapse = Math.min(this.stop_after, this.time_elapse);
this.start_at = this.now();
this.state = "stopped";
this.dump();
}
}
//输出定时器信息
dump() {
let data = [
`状态:${this.state}`,
`当前计时: ${this.elapse}ms`,
`剩余计时: ${this.rest}ms`
];
console.group(`@定时器${this.category}信息`)
console.log(...data);
console.groupEnd();
}
}
export { Timer };