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.
精彩评论