美文网首页
[TypeScript] 基于本地时间的定时器

[TypeScript] 基于本地时间的定时器

作者: 码上说 | 来源:发表于2020-05-01 00:03 被阅读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 };
    

    相关文章

      网友评论

          本文标题:[TypeScript] 基于本地时间的定时器

          本文链接:https://www.haomeiwen.com/subject/swgxghtx.html