декоратор для вызова функции 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 секунда и если включить каких-нибудь приложений, то количество вызовов функции уменьшается. Может есть какое-нибудь более изящное решение? (но больше интересует конкретно это, т.к. я его писал по наитию) |
innowed,
http://underscorejs.ru/#throttle |
innowed,
test(arr);test(arr); и ваша функция может сработать в 1 секунду более чем необходимо. |
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); |
рони,
:write: и даже в таком варианте много чего не хватает ... |
Вариант
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); |
Часовой пояс GMT +3, время: 05:14. |