Changed PeriodicalExecuter to shield from double execution
authorAlexander Ebert <ebert@woltlab.com>
Tue, 31 Jan 2012 17:14:09 +0000 (18:14 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Tue, 31 Jan 2012 17:14:09 +0000 (18:14 +0100)
Finally it's implementation is identically to Prototype's PeriodicalExecuter. Thank you guys for this fine solution!

Closes #405

wcfsetup/install/files/js/WCF.js

index 34b349dd397a8b933887fade7b72e93a4760b0ef..ec41edc29e27d282d795d9e0b4802329c9c4e7a9 100644 (file)
@@ -893,6 +893,24 @@ WCF.Clipboard = {
  */
 WCF.PeriodicalExecuter = function(callback, delay) { this.init(callback, delay); };
 WCF.PeriodicalExecuter.prototype = {
+       /**
+        * callback for each execution cycle
+        * @var object
+        */
+       _callback: null,
+       
+       /**
+        * interval id
+        * @var integer
+        */
+       _intervalID: null,
+       
+       /**
+        * execution state
+        * @var boolean
+        */
+       _isExecuting: false,
+       
        /**
         * Initializes a periodical executer.
         * 
@@ -900,21 +918,29 @@ WCF.PeriodicalExecuter.prototype = {
         * @param       integer                 delay
         */
        init: function(callback, delay) {
-               this.callback = callback;
-               this.delay = delay;
-               this.loop = true;
+               if (!$.isFunction(callback)) {
+                       console.debug('[WCF.PeriodicalExecuter] Given callback is invalid, aborting.');
+                       return;
+               }
                
-               this.intervalID = setInterval($.proxy(this._execute, this), this.delay);
+               this._callback = callback;
+               this._intervalID = setInterval($.proxy(this._execute, this), delay);
        },
        
        /**
         * Executes callback.
         */
        _execute: function() {
-               this.callback(this);
-               
-               if (!this.loop) {
-                       clearInterval(this.intervalID);
+               if (!this._isExecuting) {
+                       try {
+                               this._isExecuting = true;
+                               this._callback(this);
+                               this._isExecuting = false;
+                       }
+                       catch (e) {
+                               this._isExecuting = false;
+                               throw e;
+                       }
                }
        },
        
@@ -922,7 +948,11 @@ WCF.PeriodicalExecuter.prototype = {
         * Terminates loop.
         */
        stop: function() {
-               this.loop = false;
+               if (!this._intervalID) {
+                       return;
+               }
+               
+               clearInterval(this._intervalID);
        }
 };