Skip to content

Instantly share code, notes, and snippets.

@cantremember
Created March 23, 2012 04:10
Show Gist options
  • Save cantremember/2166671 to your computer and use it in GitHub Desktop.
Save cantremember/2166671 to your computer and use it in GitHub Desktop.
delayedCallback(function(){ ... }, delay); // invoke the callback 'delay' ms after it is last called
// returns a function that will invoke the callback 'delay' ms after it is last called
// eg. invoke the callback 500ms after the last time a key is pressed
// based on http://stackoverflow.com/questions/2219924/idiomatic-jquery-delayed-event-only-after-a-short-pause-in-typing-e-g-timew
// but fixes the following:
// (a) returns a unique timer scope on every call
// (b) propagates context and arguments from the last call to the returned closure
// and adds .cancel() and .fire() for additional callback control
// then of course, you could use underscore's _.debounce
// it doesn't have the .cancel and .fire, but you may not care :)
function delayedCallback(callback, delay) {
return (function(callback, delay) { // (2) receives the values in scope
var timer = 0; // (3a) a scoped timer
var context, args; // (3b) scoped copies from the last invocation of the returned closure
var cb = function() { callback.apply(context, args); } // (3c) called with proper context + arguments
var dcb = function() { // (4) this closure is what gets returned from .delayedCallback
context = this;
args = arguments;
window.clearTimeout(timer);
timer = window.setTimeout(cb, delay); // (5) only fires after this many ms of not re-invoking
};
dcb.cancel = function() { window.clearTimeout(timer); }; // (6a) you can cancel the delayed firing
dcb.fire = function() { this.cancel(); cb(); }; // (6b) or force it to fire immediately
return dcb;
})(callback, delay); // (1) capture these values in scope
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment