在计时器运行后,将持续时间添加到JS setTimeout

Add duration to JS setTimeout after the timer is running

本文关键字:添加 JS setTimeout 持续时间 计时器 运行      更新时间:2023-09-26

我正试图找到一种方法来模拟AS3的Timer类。

如果你不熟悉,你可以做的一件很酷的事情就是在计时器中添加持续时间,即使计时器已经在运行。这个功能有很多非常好的用途。

有人想在js中做这件事吗?

我不熟悉这个类,但你可以很容易地在JavaScript:中创建类似的东西

function Timer(callback, time) {
    this.setTimeout(callback, time);
}
Timer.prototype.setTimeout = function(callback, time) {
    var self = this;
    if(this.timer) {
        clearTimeout(this.timer);
    }
    this.finished = false;
    this.callback = callback;
    this.time = time;
    this.timer = setTimeout(function() {
         self.finished = true;
        callback();
    }, time);
    this.start = Date.now();
}
Timer.prototype.add = function(time) {
   if(!this.finished) {
       // add time to time left
       time = this.time - (Date.now() - this.start) + time;
       this.setTimeout(this.callback, time);
   }
}

用法:

var timer = new Timer(function() { // init timer with 5 seconds
    alert('foo');
}, 5000);
timer.add(2000); // add two seconds

清除超时,然后将新的超时设置为新的所需结束时间。

用另一个函数包装函数,当计时器用完时,测试是否设置了额外的时间变量。如果有,请使用新时间重新开始,否则执行该函数。

一个快速破解的脚本可能看起来像:

function test() {
    tim = new timer(function () { alert('hello'); }, 5000);   
}
function extend() {
    if (tim) { tim.addTime(5000); }   
}
function timer(func, time) {
    var self = this,
        execute = function () {
            self.execute()  
        };
    this.func = func;
    this.extraTime = 0;
    setTimeout(execute, time);
};
timer.prototype.execute = function () {
    var self = this,
        execute = function () {
            self.execute()  
        };
    if (this.extraTime) {
        setTimeout(execute, this.extraTime);
        this.extraTime = 0;
    } else {
        this.func();   
    }
};
timer.prototype.addTime = function (time) {
    this.extraTime += time;   
}
<input type="button" value="Start" onclick="test()">
<input type="button" value="Extend" onclick="extend()">

希望它能有所帮助:(只需调用具有所需时间的setInterval。

编辑:添加了停止和启动,以防你想停止你的循环:p

function Timer(defaultInterval, callback){
   var interval = defaultInterval;
   var running = true;
   function loop(){
     callback();
     if(running){
        setTimeout(function(){
           loop();
        }, interval);
     }
   }
   loop();
   return {
     setInterval: function(newInterval){
        interval = newInterval;
     },
     stop: function(){
         running = false;
     },
     start: function(){
          if(running===false){
             running = true;
             loop();
          }
     },
     add: function(milliToAdd){
          interval += milliToAdd*1;
     }
   }
}
var myTimer = Timer(250, function() { process code here });
myTimer.setInterval(1000); // sets interval to 1 second
myTimer.stop(); // stops the function
myTimer.start(); // re-starts the loop;
function Timer(func, delay) {
  var done = false;
  var callback = function() {
    done = true;
    return func();
  };
  var startTime = Date.now();
  var timeout = setTimeout(callback, delay);
  this.add = function(ms) {
    if (!done) {
      this.cancel();
      delay = delay - (Date.now() - startTime) + ms;
      timeout = setTimeout(callback, delay);
    }
  };
  this.cancel = function() {
    clearTimeout(timeout);
  };
  this.immediately = function() {
    if (!done) {
      this.cancel();      
      callback();
    }
  };
};

控制台中的快速测试

start = Date.now(); 
t = new Timer(function() { console.log(Date.now() - start); }, 1000);
t.add(200);
start = Date.now(); 
t = new Timer(function() { console.log(Date.now() - start); }, 1000000);
t.immediately();
t.immediately();

你也可以加上负数。

start = Date.now(); 
t = new Timer(function() { console.log(Date.now() - start); }, 1000);
t.add(-200);

这是我的照片。它会跟踪计时器的设置时间,并在添加时间时将差值添加到指定的时间。

var Timer = {
    set: function(p_function, p_time)
    {
        var d = new Date();
        this.timeStarted = d.getTime();
        this.func = p_function;
        this.timeout = setTimeout(p_function, p_time);
        console.log('timer started at ' + (this.timeStarted / 1000) + ' seconds');
    },
    add: function(p_time)
    {
        var d = new Date(),
            diff = d.getTime() - this.timeStarted,
            newTime = diff + p_time;
        if (this.timeout)
        {
            clearTimeout(this.timeout);
        }
        this.timeout = setTimeout(this.func, newTime);
        this.timeStarted = d.getTime();
    }
};
var myTimer = Object.create(Timer);
myTimer.set(function() {
    var d = new Date();
    console.log('Timer fired at ' + (d.getTime() / 1000) + ' seconds');
}, 10000);
setTimeout(function () {
    myTimer.add(5000);
}, 5000);

这是一个jsFiddle

请注意,由于计算和函数调用的开销,这可能需要几毫秒的时间。

我决定把我的小橡皮鸭扔进游泳池。

var setTimeout2 = function(callback, delay) {
    this.complete = false;
    this.callback = callback;
    this.delay = delay;
    this.timeout = false;
    this.dotimeout = function() {
        this.timeout = setTimeout(function() {
            this.complete = true;
            this.callback.call();
        }, this.delay);
    };
    this.start = Date.now();
    this.add = function(delay) {
        if (!this.complete) {
            this.delay = this.delay - (Date.now() - this.start) + delay;
            clearTimeout(this.timeout);
            this.dotimeout.call();
        }
    };
    return this;
};

使用

var start = Date.now();
var to = setTimeout2(function() {
    document.write(Date.now() - start);
}, 3000);
to.add(3000);

类似于这种方法,但更紧凑/没有原型