Pull to refresh

Comments 14

Извиняюсь за занудство, но к чему конструкции типа "if (!n) a; else b;" когда можно написать "if (n) b; else a;" ? К тому же, если функция заканчивается на условие и объем b >> a, то можно вообще написать "if (n) {a; return;} b;"
Простейший рефакторинг, но читать код становится проще.
Мне казалось, так код более понятен - сначала самое важное, потом остальное. А насчёт return - else короче на два символа. :) Кстати! Я сохраняю оригинальные аргументы и скоуп, а вот про возвращаемое значение забыл! Сейчас поправлю, спасибо за то, что навёл на мысль :)
Именно для взаимодействия с интерфейсом, имхо в подобном случае лучше повесить обработчиком события функцию, которая бы просто вычисляла изменения и сохраняла где-нибудь. А функция отрисовки по таймеру с нужной периодичностью проверяла бы сохраненные данные и, если нужно, отрисовывала.
Так можно, конечно, но преимущество описанного мной подхода заключается в том, что:
1) Пока интервал между вызовами не ниже заданного, изменения будут отображаться моментально. А в случае изменений по таймеру практически всегда будет какая-то задержка.
2) Функция отрисовки будет вызываться только тогда, когда нужно, без лишних вызовов.
Пример интересный.
Насколько я понял, эффект будет только если функция fn выполняется долго (дольше чем limitExecByInterval).
Кстати, если немного изменить код, то можно организовать отложенный запуск функции.
Нет, не только - эффект будет, если [кол-во вызовов за этот интервал]*[время ее исполнения] превысит limitExecByInterval, а это куда более частый случай.
я бы сделал все таки немного иначе

Function.prototype.limitExecByInterval = function(interval) {
var fn = this, result;
var timer, startTime = 0;
return function() {
if ((new Date() - startTime) >= interval)
{
timer = clearTimeout(timer); // запрещаем повторное выполнение функции после fn.apply(),
// ведь по его завершению ее выполнения может истечь интервал
// и она вызовется снова
result = fn.apply(this, arguments);
startTime = new Date();
} else
if (!timer)
{
var args = arguments;
var scope = this;
timer = setTimeout(function(){
startTime = 0; // делаем возможным выполнение функции fn, при любом раскладе
args.callee.apply(scope, args);
}, interval);
}
return result;
}
}
Ловко придумано! В таком варианте, правда, после исполнения функции и повторного вызова перед концом интервала ее исполнение откладывается не на этот конец, а на текущее время + интервал. Т.е. вместо interval в setTimeout наверное нужно передавать interval + startTime - new Date(). Мне в нём не нравится одно - слишком много операции с датой (вместо просто парочки флажков в моём случае) - код более сложный для понимания и потенциально менее производительный. А какие преимущества?
Кхм.. Ну тогда что-то вроде:

Function.prototype.limitExecByInterval = function(interval) {
var fn = this;
var timer, expireTime = 0;
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;
var scope = this;
timer = setTimeout(function(){
expireTime = 0;
args.callee.apply(scope, args);
}, elapseTime);
}
}
}
</pre>
ЗЫ Насчет того что код более сложный для понимания - кому как :)
Хороший материал!
Я точно так же (идея) разруливал события с jquery. Особенно перерисовку по изменению события в web интерфейсе своей админки.
Но код позволил сделать мою функцию чуть более гибкой.
В чём выражалась большая гибкость? Буду рад услышать идеи :)
а я был бы рад еще и увидеть такие решения.

начал разруливать jQuery, а тут привалило задание на создание меню с плавным движением кнопок (фреймворк справился с плавностью и движением), но при этом появилась проблема частоты вызова этого самого движения. Т.е. если много раз провести над кнопкой, то она будет двигаться туда-сюда столько раз, сколько над ней водили
И даже не знаю как к проблеме подойти(
Материалы не для новичков, наверное, можно не упрощать отрубанием Function.prototype и т.п.
Sign up to leave a comment.

Articles