Add duration to JS setTimeout after timer starts

I am trying to figure out a way to emulate the AS3 Timer class.

If you are not familiar, one of the interesting things you can do is add a timer duration, even if it is already running. This functionality has many very nice uses.

Anyone have thoughts on this in js?

+7
source share
7 answers

I am not familiar with this class, but you can easily create something like this in 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); } } 

Using:

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

Clear the timeout, then set the new timeout to the new desired end time.

+3
source

There you hope this helps :) just call setInterval with the time you want to have.

Edit: added stop and start in case you want to stop the loop: 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; 
+2
source

Wrap the function in another, and when the timer ends, check if the optional temporary variable is set. If there is one, start again from a new time, otherwise execute a function.

A quickly hacked script might look like this:

 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()"> 
+1
source

Here is my picture. It keeps track of when the timer has been set, and adds the difference to the specified time when you add the time.

 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 jsFiddle

Note that due to the overhead of computing and function calls, this can take several milliseconds.

+1
source

I decided to throw my little rubber band into the pool.

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

Using

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

similar to this approach , but a little more compact / no proto

0
source
 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(); } }; }; 

quick test in the console

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

You can also add negative values.

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

All Articles