Skip to content

Instantly share code, notes, and snippets.

@purtuga
Created January 4, 2014 16:49
Show Gist options
  • Save purtuga/8257269 to your computer and use it in GitHub Desktop.
Save purtuga/8257269 to your computer and use it in GitHub Desktop.
A jQuery utility leveraging the Deferred Class to execute a code block in the future after a given condition is meet. See blog post for more: http://wp.me/p2kCXW-35
/*! Copyright (c) 2014 - Paul Tavares - purtuga - @paul_tavares - MIT License */
;(function($){
/**
* Delays the execution of a function until an expression returns true.
* The expression is checked every 100 milliseconds for as many tries
* as defined in in the attempts option
*
* @param {Object} options
* @param {Function} options.when
* Function to execute on every interval.
* Must return true (boolean) in order for
* options.do to be executed.
* @param {Function} [options.exec]
* Function to be executed once options.when()
* returns true.
* @param {Interger} [options.interval=100]
* How long to wait in-between tries.
* @param {Interger} [options.attempts=100]
* How many tries to use before its considered
* a failure.
* @param {Interger} [options.delayed=0]
* Number of miliseconds to wait before execution
is started. Default is imediately.
*
* @return {jQuery.Promise}
*
* @example
*
* $.doWhen({
* when: function(){
* return false;
* },
* exec: function(){
* alert("never called given false response on when param!");
* }
* })
* .fail(function(){
* alert('ALERT: FAILED CONDITION');
* })
* .then(function(){
* alert("resolved.");
* });
*
*/
$.doWhen = function(options) {
return $.Deferred(function(dfd){
var opt = $.extend({}, {
when: null,
exec: function(){},
interval: 100,
attempts: 100,
delayed: 0
},
options,
{
checkId: null
}),
startChecking = function(){
// Check condition now and if true, then resolve object
if (opt.when() === true) {
opt.exec.call(dfd.promise());
dfd.resolve();
return;
}
// apply minimal UI and hide the overlay
opt.checkId = setInterval(function(){
if (opt.attempts === 0) {
clearInterval(opt.checkId);
dfd.reject();
} else {
--opt.attempts;
if (opt.when() === true) {
opt.attempts = 0;
clearInterval(opt.checkId);
opt.exec.call(dfd.promise());
dfd.resolve();
}
}
}, opt.interval);
};
if (opt.delayed > 0) {
setTimeout(startChecking, Number(opt.delayed));
} else {
startChecking();
}
}).promise();
};
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment