Global Timer in Javascript with Multiple Callbacks

后端 未结 3 664
暗喜
暗喜 2021-01-19 10:39

I want to create a global timer object in javascript and then be able to add callbacks to it on the fly. This way I can just use one global timer in my script to execute all

相关标签:
3条回答
  • 2021-01-19 11:05

    Create a GlobalTimer object and give it the ability to register callback functions and cancel itself.

    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 讨论(0)
  • 2021-01-19 11:20

    Have the interval fire an event. The subscribing functions can listen to the event (or not) and choose to fire or not according to their own logic.

    The jQuery way of doing this would be:

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

    Then later inside otherObject ...

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

    There are obviously other ways of implementing events.

    As the google link in the comments notes, this isn't the option with the highest performance. It is flexible and relatively forgiving however.

    0 讨论(0)
  • 2021-01-19 11:20

    Just a slightly modified version of aekeus approach. Now with pause- & resumable timers, third arguments and a faster 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;
            }
        };
    }
    

    You can pass in extra-arguments like with default setInterval's (even in IE lt 9):

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

    Usage example:

    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;
    
    0 讨论(0)
提交回复
热议问题