Skip to content

Instantly share code, notes, and snippets.

@kof
Created January 21, 2011 14:48
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save kof/789765 to your computer and use it in GitHub Desktop.
Save kof/789765 to your computer and use it in GitHub Desktop.
deffered function execution
(function(global){
var $ = global.jQuery || global,
D = Date,
now = D.now || function() {
return (new D).getTime();
};
// if once is true, fn will be executed only once if called more then one times during the time in delay.
// if once is not defined or false, fn will be executed periodically, period is delay.
$.defer = function(fn, delay, once) {
if (!delay || typeof delay === 'boolean') {
once = delay;
delay = 100;
}
var ret,
lasttime, currenttime,
enabled = true,
wrapper, enable;
if (once) {
wrapper = function() {
currenttime = now();
if (!lasttime || currenttime - lasttime > delay) {
ret = fn.apply(this, arguments);
}
lasttime = currenttime;
return ret;
};
} else {
enable = function() {
enabled = true;
};
wrapper = function() {
if (enabled) {
ret = fn.apply(this, arguments);
enabled = false;
setTimeout(enable, delay);
}
return ret;
};
}
// Set the guid of unique handler to the same of original handler, so it can be removed
if ( $.guid ) {
wrapper.guid = fn.guid = fn.guid || $.guid++;
}
return wrapper;
};
}(this));
@kof
Copy link
Author

kof commented Jan 21, 2011

If once=true, Date.now will be used instead of timeout, because otherwise setTimeout and clearTimeout should be called every time and it is more costly then Date.now.

Here is an example where you will see 2 log entries, from the 1. call and from 3. This is because of default delay of 100ms, so the fn is called every 100ms.
var fn = defer(function(){ console.log(6666); });
fn();
setTimeout(fn, 80);
setTimeout(fn, 110)

Here is an example where you will see only 1 log entry, the first one. Because second call resets lastexec timestamp, so the next call can be executed in 100 ms, but it tries to execute in 30 ms.
var fn = defer(function(){ console.log(6666); }, true);
fn();
setTimeout(fn, 80);
setTimeout(fn, 110)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment