Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 02.07.2016, 18:56
Аспирант
Отправить личное сообщение для innowed Посмотреть профиль Найти все сообщения от innowed
 
Регистрация: 27.03.2015
Сообщений: 78

декоратор для вызова функции n раз в секунду
Здравствуйте! Хочу решить такую задачку, мой код сейчас:
function callWrap(f, count){
  var now = Date.now();
  return function(){
      var calls=0;
      while(Date.now()-now < 1000 && calls<count){ //вызывать функцию не чаще чем count раз в секунду
        f.apply(this, arguments);
        calls++;
      }
  };  
}

//"медленная" функция
var arr = [];
for (var i = 0; i < 1000; i++) arr[i] = 0;
function walkLength(arr) {
  for (var i = 0; i < arr.length; i++) arr[i]++;
  console.log('done');
}

var test = callWrap(walkLength, 7000); //обёртываем функцию в декоратор
test(arr);


Но я не могу понять, правильно ли такое решение? Условия вроде как выполняются, чисто визуально проходит 1 секунда и если включить каких-нибудь приложений, то количество вызовов функции уменьшается. Может есть какое-нибудь более изящное решение? (но больше интересует конкретно это, т.к. я его писал по наитию)
Ответить с цитированием
  #2 (permalink)  
Старый 02.07.2016, 19:00
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

innowed,
http://underscorejs.ru/#throttle
Ответить с цитированием
  #3 (permalink)  
Старый 02.07.2016, 19:07
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,069

innowed,
test(arr);test(arr); и ваша функция может сработать в 1 секунду более чем необходимо.
Ответить с цитированием
  #4 (permalink)  
Старый 02.07.2016, 19:24
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,069

innowed,
function callWrap(f, count){
  var now, calls;
  return function(){
      if(!now||Date.now()- now > 1000) {now = Date.now();calls = 0};
      while(Date.now()-now < 1000 && calls<count){ //вызывать функцию не чаще чем count раз в секунду
        f.apply(this, arguments);
        calls++;
      }
  };
}

//"медленная" функция
var arr = [];
for (var i = 0; i < 1000; i++) arr[i] = 0;
function walkLength(arr) {
  for (var i = 0; i < arr.length; i++) arr[i]++;
  console.log('done');
}

var test = callWrap(walkLength, 7000); //обёртываем функцию в декоратор
test(arr);
test(arr); //тут  запуска не будет; секунда ещё не прошла но запущено 7000 функций
window.setTimeout(function() {
test(arr);
},15000)
test(arr);

Последний раз редактировалось рони, 02.07.2016 в 19:29.
Ответить с цитированием
  #5 (permalink)  
Старый 02.07.2016, 19:35
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,069

рони,
и даже в таком варианте много чего не хватает ...
Ответить с цитированием
  #6 (permalink)  
Старый 02.07.2016, 22:17
Аватар для Vlasenko Fedor
Профессор
Отправить личное сообщение для Vlasenko Fedor Посмотреть профиль Найти все сообщения от Vlasenko Fedor
 
Регистрация: 13.03.2013
Сообщений: 1,572

Вариант
Function.prototype.limitExecByInterval = function (interval) {
    var fn = this, expireTime = 0, timer;
    return function () {
        var elapseTime = expireTime - new Date();
        if (elapseTime <= 0) {
            timer = clearTimeout(timer);
            fn.apply(this, arguments);
            expireTime = Number(new Date()) + interval;
        } else if (!timer) {
            var args = arguments, scope = this;
            timer = setTimeout(function () {
                expireTime = 0;
                args.callee.apply(scope, args);
            }, elapseTime);
        }
    }
};
var myFunc = function() {};
var myLimitedFunc = myFunc.limitExecByInterval(150);
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
google maps api - через раз отображаются title для маркера на карте shurik_shink Общие вопросы Javascript 0 17.04.2016 12:22
PopUp как выполнить код один раз для сессии kznsky Events/DOM/Window 5 03.03.2015 13:48
Вызов функции каждую секунду. can2zia jQuery 8 14.08.2009 18:41
Проверка существования входного параметра для функции Axe Я не знаю javascript 2 25.05.2009 14:58
Применение функции для каждого элемента sergeygerasimov jQuery 2 26.11.2008 11:15