So I wrote a periodic execution function for jQuery, similar to the
PeriodicExecuter function of prototype. I'd like some feedback as to
it's usefulness (or non-usefullness). This is my first plugin, so any
suggestions as to what to change are appreciated (should I use
jQuery.extend to create the plugin, or just assign it like this,
etc).

I'm trying to find a solution to a bug in firefox (but NOT internet
explorer) where the parallel execution of the callback function is not
shielded by the code (prototype's PeriodicExecuter has the same
problem - their example code *does not work* in firefox (firebug & web
developer plugin installed). Any comments are appreciated.

/*
 * jquery-periodic.js
 *
 * Adds a "periodic" function to jQuery which takes a callback and
options for the frequency (in seconds) and a
 * boolean for allowing parallel execution of the callback function
(shielded from exceptions by a try..finally block.
 * The first parameter passed to the callback is a controller object.
 *
 * Return falsy value from the callback function to end the periodic
execution.
 *
 * For a callback which initiates an asynchronous process:
 * There is a boolean in the controller object which will prevent the
callback from executing while it is "true".
 *   Be sure to reset this boolean to false when your asynchronous
process is complete, or the periodic execution
 *   won't continue.
 *
 * To stop the periodic execution, you can also call the "stop" method
of the controller object, instead of returning
 * false from the callback function.
 *
 */
 jQuery.periodic = function (callback, options) {
      callback = callback || (function() { return false; });

      options = jQuery.extend({ },
                              { frequency : 10,
                                allowParallelExecution : false},
                              options);

      var currentlyExecuting = false;
      var timer;

      var controller = {
         stop : function () {
           if (timer) {
             window.clearInterval(timer);
             timer = null;
           }
         },
         currentlyExecuting : false,
         currentlyExecutingAsync : false
      };

      timer = window.setInterval(function() {
         if (options.allowParallelExecution || !
(controller.currentlyExecuting || controller.currentlyExecutingAsync))
{
            try {
                 controller.currentlyExecuting =
true;
                 if (!(callback(controller))) {
                     controller.stop();
                 }
             } finally {
              controller.currentlyExecuting = false;
            }
         }
      }, options.frequency * 1000);
};

Reply via email to