Функция Javascript: с момента последней попытки прошло полсекунды? - PullRequest
3 голосов
/ 19 апреля 2010

Я бы хотел создать функцию, которая возвращает false, если она была вызвана менее полсекунды назад.

timething.timechill=function(){
    var last
    if (last){
            if ((now.getTime()-last)>500){
                    return true
            }
            else{

                    return true
            }
    }
    else {
            last=now.getTime()
            return false
    }}

Есть идеи? Я хотел бы избежать setTimeout () и игнорировать ввод, если он идет слишком быстро, чтобы избежать переполнения. Это хорошая практика?

Ответы [ 4 ]

5 голосов
/ 19 апреля 2010
timething.timechill = (function () {
    var lastCall = 0;
    return function () {
        if (new Date() - lastCall < 500)
            return false;
        lastCall = new Date();
        //do stuff
    }
})();

Идея в том, что (function() { ... })(); создаст анонимную функцию и сразу же запустит ее. timething.timechill не назначена эта функция. Вместо этого ему присваивается внутренняя функция , возвращаемая этой функцией.

Обратите внимание, что lastCall не объявлено (используется ключевое слово var) внутри этой внутренней функции. И когда внешняя функция возвращается, lastCall не исчезает, потому что внутренняя функция «заключила» ее в силу того факта, что она ссылается на переменную.

Когда вы запустите timething.timechill позже и обнаружите эту переменную, она будет искать переменную вне области действия функции и найдет ту, которая была объявлена ​​ранее. При возврате переменная по-прежнему не исчезает, поскольку она была объявлена ​​вне области действия функции.

Трудно четко объяснить эту концепцию, но она очень полезна, потому что lastCall невидим для остальной части вашего кода, который не нуждается в его просмотре.

1 голос
/ 19 апреля 2010

Я не думаю, что это хорошая идея. В зависимости от того, как вы вызываете этот метод, это может привести к поведению «бесконечного цикла». С setTimeout вы выполняете асинхронную операцию - вы не блокируете браузер, ожидая, пока пройдет время. Большинство браузеров обнаружат код блокировки и отключат ваш скрипт.

0 голосов
/ 19 апреля 2010

«Последняя» переменная должна храниться в другом объекте, таком как объект окна для глобальной переменной или объект timething здесь. И я никогда не слышал о «сейчас» объекте!?

timething.timechill = function(){

    if (!timething._last_timechill){

       if ((new Date())-timething._last_timechill >= 500) return true;
       else return false;

    } else {

        timething._last_timechill = new Date();
        return false;

   }

}

Вы можете заменить "timething" на "window" в функции, если хотите.

РЕДАКТИРОВАТЬ: Как отмечали другие, вы можете также сохранить свою переменную _last_timechill в закрытии.

0 голосов
/ 19 апреля 2010

Ваша определенная функция всегда будет возвращать false, потому что переменная last никогда нигде не сохраняется. Вы можете хранить его как свойство объекта или хранить внутри замыкания.

Вот пример закрытия:

timething.timechill = (function() {
    var last = 0;

    function timechill() {
        var now;

        now = new Date().getTime();
        if (last) {
            if (now - last > 500) {
                // It's been long enough, allow it and reset
                last = now;
                return true;
            }
            // Not long enough
            return false;
        }

        // First call
        last = now;
        return false;
    }

    return timechill;
})());

Использует анонимную функцию определения объема для построения вашей функции timechill как замыкания над переменной last. Анонимная функция определения объема возвращает ссылку на функцию timechill, которая присваивается timething.timechill. Ничто, кроме функции timechill, не может получить доступ к last, оно полностью приватное.

(Я уверен, что реальная логика функции могла бы быть немного изменена, но я думаю, что это довольно близко к вашему оригиналу, за исключением одного места, куда вы возвращали true, где, я думаю, вы хотели false.)

Является ли это хорошей идеей, полностью зависит от вашего варианта использования. Я бы не стал зацикливаться на вышесказанном. :-) Но если вы используете его, чтобы вызвать что-то вроде SO, «Вы можете оценивать комментарий только каждые пять секунд», это было бы хорошо, хотя в этом случае я бы, вероятно, обобщил это.

...