开发者

Javascript function: Has half a second passed since last time you tried?

I'd like to build a function that returns false if it's been called less that half a second ago.

timething.timechill=f开发者_开发问答unction(){
    var last
    if (last){
            if ((now.getTime()-last)>500){
                    return true
            }
            else{

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

Any ideas? I'd like to avoid setTimeout() and ignore input if it's coming too quick to avoid overflow. Is this a good practice?


timething.timechill = (function () {
    var lastCall = 0;
    return function () {
        if (new Date() - lastCall < 500)
            return false;
        lastCall = new Date();
        //do stuff
    }
})();

The idea here is that (function() { ... })(); will create an anonymous function and run it immediately. timething.timechill is not assigned this function. Instead, it is assigned the inner function returned by this function.

Note that lastCall is not declared (using the var keyword) within that inner function. And when the outer function returns, lastCall doesn't disappear because the inner function has "enclosed" it by virtue of the fact that it refers to the variable.

When you run timething.timechill later and it encounters this variable, it will search outside the function's scope for the variable and find the one that was declared earlier. When it returns, the variable still does not disappear, since it was declared outside the function's scope.

It is hard to explain this concept clearly, but it is very useful because lastCall is invisible to the rest of your code which doesn't need to see it.


I don't think this is a good idea. Depending on how you call this method, it may lead to an "infinite loop" behavior. With setTimeout you have asynchronous operation - you don't block the browser, while waiting for time to pass. Most browsers will detect blocking code and disable your script.


The "last" variable has to be stored in another object, such as the window object for a global variable or the timething object here. And I have never heard of a "now" object!?

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;

   }

}

You can replace "timething" with "window" in the function if you like.

EDIT: As the others pointed out, you can alsostore your _last_timechill variable in a closure.


Your function as defined will always return false because the last variable is never saved anywhere. You could hold it as a property of an object, or you can hold it within a closure.

Here's a closure example:

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

That uses an anonymous scoping function to build your timechill function as a closure over the last variable. The anonymous scoping function returns a reference to the timechill function, which gets assigned to timething.timechill. Nothing other than the timechill function can access last, it's entirely private.

(I'm sure the actual logic of the function could be refactored a bit, but I think that's pretty close to your original except there was one place you were returning true where I think you wanted false.)

Whether this is a good idea depends entirely on your use-case. I wouldn't busy-loop on the above. :-) But if you're using it to pop up something like SO's "You can only rate a comment once every five seconds" things, it would be fine, although in that case I'd probably generalize it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜