Глобальный таймер в Javascript с несколькими обратными вызовами - PullRequest
4 голосов
/ 23 апреля 2010

Я хочу создать объект глобального таймера в javascript, а затем иметь возможность добавлять к нему обратные вызовы на лету.Таким образом, я могу просто использовать один глобальный таймер в моем скрипте для выполнения всех действий с определенным интервалом, а не тратить ресурсы, используя кратные значения.

Вот как я хочу иметь возможность собирать вещи вместе:

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();

Как бы я позволил привязать любые числовые функции (большинство из которых являются функциями внутри других объектов) к запуску с интервалом моего таймера на лету?

Ответы [ 3 ]

6 голосов
/ 23 апреля 2010

Создайте объект GlobalTimer и дайте ему возможность регистрировать функции обратного вызова и отменять себя.

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);
2 голосов
/ 23 апреля 2010

Интервал запускает событие. Подписывающиеся функции могут прослушивать событие (или нет) и выбирать, запускать или нет в соответствии со своей логикой.

Способ jQuery сделать это будет:

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

Потом внутри otherObject ...

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

Существуют и другие способы реализации событий.

Как показывает ссылка Google в комментариях, это не вариант с самой высокой производительностью. Однако он гибкий и относительно прощающий.

0 голосов
/ 01 апреля 2013

Просто слегка измененная версия подхода Aekeus.Теперь с таймерами паузы и возобновления, третьим arguments и более быстрым callbacks -циклом:

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;
        }
    };
}

Вы можете передать extra - arguments как по умолчанию setInterval (даже в IE lt 9):

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

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

Пример использования:

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...