UNPKG

pausable-timer

Version:

一个可随时暂停以及恢复的定时器

120 lines (112 loc) 2.85 kB
interface IOptions { timer: number; mode: "loop" | "once"; callback: () => any; debug?: boolean; } type modeType = "loop" | "once"; class PausableTimer { // timeID private id!: number; // 周期间隔 private timer = 0; // 起点 private startTime = 0; // 距离下一次调用时间 private diffTime: number = 0; // 调试模式 private isDubgger!: boolean | undefined; // 回调函数 private callback = () => {}; private mode: modeType; constructor(option: IOptions) { console.log(globalThis.window ? "运行在浏览器" : "运行在其它运行时"); this.isDubgger = option.debug; // 在ts以外的环境判断下 this.checkMode(option.mode); this.timer = option.timer; this.mode = option.mode; this.callback = option.callback; // 开始计时 this.start(); } // 启动 start = () => { this.isDubgger && console.log("调用start成功", this.getState()); this.stop(); this.id = setTimeout( () => { this.isDubgger && console.log("回调触发", this.getState()); // 重置中断点 this.callback(); this.mode === "loop" && this.start(); }, (() => { if (this.diffTime > 0) { return this.diffTime; } this.startTime = this.getNowTime(); return this.timer; })() ); this.diffTime = 0; }; // 恢复 resume = () => { if (this.diffTime === 0) { return; } this.isDubgger && console.log("恢复", this.getState()); this.start(); }; // 暂停 pause = () => { if (this.diffTime) { return; } this.diffTime = this.timer - (this.getNowTime() - this.startTime); this.isDubgger && console.log("暂停", this.getState()); this.diffTime < 0 && this.callback(); this.stop(); }; after(delay: number) { this.pause(); setTimeout(this.resume, delay); } // 停止 stop = () => { this.id && clearTimeout(this.id); this.id = 0; }; getNowTime = () => { // performance.now()不会受线程阻塞之类的影响,相对更准确 return globalThis.window?.performance?.now() || Date.now(); }; // 改变模式 setMode = (mode: modeType, isReset?: false) => { this.checkMode(mode); isReset && this.reset(); this.mode = mode; this.isDubgger && console.log("模式改变", this.getState()); this.start(); }; // 回到最初的美好 reset = () => { this.diffTime = 0; this.stop(); }; getState = () => { const { diffTime, startTime, mode, timer } = this; return { diffTime, startTime, timer, mode, }; }; checkMode = (mode: modeType) => { if (!["loop", "once"].includes(mode)) throw new Error(`请指定正确的运行模式,"loop" | "once"`); }; } export default PausableTimer;