js 定時器 Timer

  1 /* Timer 定時器 
  2 
  3 parameter:
  4     func: Function; //定時器運行時的回調; 默認 null
  5     speed: Number; //延遲多少毫秒執行一次 func; 默認 3000;
  6     step: Integer; //執行多少次: 延遲speed毫秒執行一次 func; 默認 Infinity;
  7     isStart: bool; //初始化時是否自動啟動一次計時器(前提是 func 已被定義); 默認 true
  8 
  9 attribute:
 10     func, speed, step;    //這些屬性可以隨時更改;
 11 
 12     //只讀屬性
 13     readyState: String;    //定時器狀態; 可能值: '', 'start', 'running', 'done'; ''表示定時器從未啟動
 14     number: Number;        //運行的次數
 15 
 16 method:
 17     start(func, speed): this;    //啟動定時器 (如果定時器正在運行則什麼都不會做)
 18     restart(): undefined;        //重啟定時器
 19     stop(): undefined;            //停止定時器
 20 
 21 demo:
 22     //每 3000 毫秒 列印一次 timer.number, 重複 Infinity 次;
 23     new Timer(timer => console.log(timer.number), 3000, Infinity);
 24 
 25 */
 26 class Timer{
 27 
 28     #restart = -1;
 29     #speed = 0;
 30     #isRun = false;
 31     #i = 0;
 32     #readyState = ''; //start|running
 33     //#paused = -1;
 34 
 35     get number(){
 36         return this.#i;
 37     }
 38     
 39     get readyState(){
 40         return this.#i >= this.step ? 'done' : this.#readyState;
 41     }
 42 
 43     /* get paused(){
 44         return this.#paused !== -1;
 45     }
 46 
 47     set paused(v){
 48         if(v === true){
 49             
 50             if(this.#i < this.step){
 51                 if(this.#paused === -1) this.#paused = this.#i;
 52                 this.stop();
 53             }
 54 
 55         }
 56 
 57         else if(this.#paused !== -1){
 58             this.restart();
 59             this.#i = this.#paused;
 60             this.#paused = -1;
 61 
 62         }
 63 
 64     } */
 65 
 66     constructor(func = null, speed = 3000, step = 1, isStart = true){
 67         this.func = func;
 68         this.speed = speed;
 69         this.step = step;
 70         //this.onDone = null;
 71     
 72         if(isStart === true && this.func !== null) this.restart();
 73 
 74     }
 75 
 76     copy(timer){
 77         this.func = timer.func;
 78         this.speed = timer.speed;
 79         this.step = timer.step;
 80         return this;
 81     }
 82 
 83     clone(){
 84         return new this.constructor().copy(this);
 85     }
 86 
 87     start(func, time){
 88         if(typeof func === 'function') this.func = func;
 89         if(UTILS.isNumber(time) === true) this.speed = time;
 90         this.restart();
 91 
 92         return this;
 93     }
 94 
 95     restart(){
 96         if(this.#isRun === false){
 97             setTimeout(this._loop, this.speed);
 98             this.#isRun = true;
 99             this.#restart = -1;
100             this.#i = 0;
101             this.#readyState = 'start';
102             
103         }
104 
105         else{
106             this.#restart = Date.now();
107             this.#speed = this.speed;
108 
109         }
110 
111     }
112 
113     stop(){
114         if(this.#isRun === true){
115             this.#restart = -1;
116             this.#i = this.step;
117         }
118 
119     }
120 
121     _loop = () => {
122 
123         //重啟計時器
124         if(this.#restart !== -1){
125             
126             let gone = Date.now() - this.#restart;
127             this.#restart = -1;
128             
129             if(gone >= this.#speed) gone = this.speed;
130             else{
131                 if(this.#speed === this.speed) gone = this.#speed - gone;
132                 else gone = (this.#speed - gone) / this.#speed * this.speed;
133             }
134             
135             setTimeout(this._loop, gone);
136             
137             this.#i = 1;
138             if(this.func !== null) this.func(this);
139 
140         }
141 
142         //正在運行
143         else if(this.#i < this.step){
144 
145             setTimeout(this._loop, this.speed);
146 
147             this.#i++;
148             if(this.#readyState !== 'running') this.#readyState = 'running';
149             if(this.func !== null) this.func(this);
150 
151         }
152 
153         //完成
154         else this.#isRun = false;
155 
156     }
157 
158 }

完整程式碼

 

parameter:
    func: Function; //定時器運行時的回調; 默認 null
    speed: Number; //延遲多少毫秒執行一次 func; 默認 3000;
    step: Integer; //執行多少次: 延遲speed毫秒執行一次 func; 默認 Infinity;
    isStart: bool; //初始化時是否自動啟動一次計時器(前提是 func 已被定義); 默認 true

attribute:
    func, speed, step;  //這些屬性可以隨時更改;

    //只讀屬性
    readyState: String; //定時器狀態; 可能值: ”, ‘start’, ‘running’, ‘done’; ”表示定時器從未啟動
    number: Number;     //運行的次數

method:
    start(func, speed): this;   //啟動定時器 (如果定時器正在運行則什麼都不會做)
    restart(): undefined;       //重啟定時器
    stop(): undefined;          //停止定時器

demo:
    //每 3000 毫秒 列印一次 timer.number, 重複 Infinity 次;
    new Timer(timer => console.log(timer.number), 3000, Infinity);