2010-04-23 6 views
4

Je veux créer un objet temporisateur global en javascript et ensuite pouvoir y ajouter des rappels à la volée. De cette façon, je peux simplement utiliser une minuterie globale dans mon script pour exécuter toutes les actions à un certain intervalle plutôt que gaspiller des ressources en utilisant des multiples.Minuteur global en Javascript avec plusieurs rappels

Voilà comment je veux être en mesure de reconstituer les choses ensemble:

var timer = new function() { 
clearInterval(this.interval); 

//[1] At this point I want the Callbacks to be run 

var self = this; 
setTimeout(function() {self.timer()}, 200); 
} 

function otherObject = new function() { 
    //When created I want to bind my object's function called cb to the global timer at [1] 
} 

otherObject.prototype.cb = function() { 
    //Stuff that should be done every time the timer is run 
} 

var someObject = new otherObject(); 

Comment pourrais-je le rendre bind possible toutes les fonctions numériques (dont la plupart sont des fonctions au sein d'autres objets) pour exécuter à l'intervalle de mon minuteur à la volée?

+4

Voici un grand article addres chantez quelques avantages/inconvénients avec cette idée: http://googlecode.blogspot.com/2009/07/gmail-for-mobile-html5-series-using.html des gens de google. Plus précisément, voir la section "Une minuterie à haute fréquence pour les gouverner tous" –

Répondre

5

Créer un objet GlobalTimer et lui donner la possibilité d'enregistrer des fonctions de rappel et de s'annuler.

function makeGlobalTimer(freq) { 
    freq = freq || 1000; 

    // array of callback functions 
    var callbacks = []; 

    // register the global timer 
    var id = setInterval(
    function() { 
     var idx; 
     for (idx in callbacks) { 
     callbacks[idx](); 
     } 
    }, freq); 

    // return a Global Timer object 
    return { 
    "id": function() { return id; }, 
    "registerCallback": function(cb) { 
     callbacks.push(cb); 
    }, 
    "cancel": function() { 
     if (id !== null) { 
     clearInterval(id); 
     id = null; 
     } 
    } 
    }; 
} 

var gt = makeGlobalTimer(500); 
gt.registerCallback(function() { 
         console.log("a"); 
        }); 

gt.registerCallback(function() { 
         console.log("b"); 
        }); 

setTimeout(function() { gt.cancel(); }, 5000); 
+0

Merci beaucoup. C'est exactement le genre de chose que je cherchais. Très apprécié! –

2

L'intervalle déclenche un événement. Les fonctions d'abonnement peuvent écouter l'événement (ou non) et choisir de tirer ou non selon leur propre logique.

The jQuery way de le faire serait:

(function() { 
    setInterval(function() { 
    $(document).trigger('heartbeat-of-the-universe'); 
    }, 200); 
})(); 

Puis, plus tard dans otherObject ...

$(document).bind('heartbeat-of-the-universe', this.cb); 

Il y a évidemment d'autres moyens de mise en œuvre des événements.

Comme le lien google dans les commentaires, ce n'est pas l'option la plus performante. Il est souple et relativement pardonnant cependant.

0

Juste une version légèrement modifiée de l'approche d'aekeus. Maintenant, avec Pause- & minuteries, réactivables troisième arguments et plus rapide callbacks -loop:

function Interval(callback, freq) { 

    // array of callback functions 
    var args = arguments, 
     callbacks = [callback], 
     paused = false; 

    // register the global timer 
    var id = setInterval(function() { 
     if(paused) return; 
     var len = callbacks.length, 
      i = len; 
     while(i--) callbacks[len - 1 - i].apply(Interval, Array.prototype.slice.call(args, 2, args.length)); 
    }, freq); 

    // return a Global Timer object 
    return { 
     id: function() { 
      return id; 
     }, 
     add: function (cb) { 
      callbacks.push(cb); 
     }, 
     clear: function() { 
      if (id === null) return; 
      clearInterval(id); 
      id = null; 
     }, 
     pause: function(){ 
      paused = true; 
     }, 
     resume: function(){ 
      paused = false; 
     } 
    }; 
} 

Vous pouvez passer supplémentaire - arguments comme avec s par défaut setInterval de »(même dans IE 9 lt):

function callback(date) { 
    console.log(date); 
} 

var interval = Interval(callback, 1000, new Date); 

exemple d'utilisation:

var interval = Interval(function() { 
    console.log("init", new Date); 
}, 1000); 

interval.add(function() { 
    console.log("a", new Date); 
}); 

interval.add(function() { 
    console.log("b", new Date); 
}); 

document.onmousedown = interval.pause; 
document.onmouseup = interval.resume;