1. 程式人生 > 其它 >js 定時器 Timer

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);