在计时器运行后向JS setTimeout添加持续时间

时间:2011-10-17 19:40:02

标签: javascript

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

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

任何人都有在js中这样做的想法吗?

7 个答案:

答案 0 :(得分:12)

我不熟悉这个类,但您可以轻松地在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

答案 1 :(得分:3)

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

答案 2 :(得分:2)

你希望它有所帮助:)只需用你想要的时间调用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;

答案 3 :(得分:2)

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

quickly hacked together script可能如下所示:

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()">

答案 4 :(得分:1)

这是我的镜头。它会跟踪设置计时器的时间,并在您添加时间时将差异添加到指定的时间。

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

Here's a jsFiddle

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

答案 5 :(得分:1)

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

答案 6 :(得分:0)

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

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

类似于this approach但更紧凑/没有原型