admin管理员组

文章数量:1315376

I've looked at many different solutions to this, none of which worked. I know it has something to do with setTimeout, but I don't know how to implement it properly.

function myfunction()
{
//the function
//wait for 1 second before it can be ran again
}

To clarify: I don't want to call the function at a regular interval, I want to be able to enforce a delay before the function can be called again.

I've looked at many different solutions to this, none of which worked. I know it has something to do with setTimeout, but I don't know how to implement it properly.

function myfunction()
{
//the function
//wait for 1 second before it can be ran again
}

To clarify: I don't want to call the function at a regular interval, I want to be able to enforce a delay before the function can be called again.

Share Improve this question edited Jun 30, 2014 at 0:40 user1864610 asked Jun 30, 2014 at 0:31 dandan 1471 gold badge2 silver badges8 bronze badges 4
  • setTimeout(myfunction, 1000) – Brad Commented Jun 30, 2014 at 0:33
  • 2 Do you want to wait one second and then automatically call the function again, or do you want to enforce a delay of one second before it's possible to run the function? – user1864610 Commented Jun 30, 2014 at 0:35
  • I want to enforce a delay before it can be ran again, after having been called. – dan Commented Jun 30, 2014 at 0:36
  • @user3788705 Will it be called repeatedly in succession or do you want something like: 1 second: call it, then, at t = 2 seconds, you are allowed to call it again; however, you don't have to. – royhowie Commented Jun 30, 2014 at 0:38
Add a ment  | 

6 Answers 6

Reset to default 4
var lastTime = 0;

function myFunction() {
    var now = new Date().getTime(); // Time in milliseconds
    if (now - lasttime < 1000) {
        return;
    } else {
        lastTime = now;
    }
    // rest of function
}

You don't need to use setTimeout at all. The following is similar to other answers, but uses a closure to remember the last time the function ran rather than a global variable.

var myFunction = function() {
  var lastTime = new Date();
  return function() {
    var now = new Date();
    if ((now - lastTime) < 1000) return;
    lastTime = now; 

    /* do stuff */

  };
}());

I think the easiest solution would be to hold a boolean variable and reset it to true after a given delay.

fiddle

HTML

<button id="clickme">click me!</button>

JavaScript

var canGo = true,
    delay = 1000; // one second
var myFunction = function () {
    if (canGo) {
        canGo = false;
        // do whatever you want
        alert("Hi!");
        setTimeout(function () {
            canGo = true;
        }, delay)
    } else {
        alert("Can't go!");
    }
}


$("#clickme").click(function(){
    myFunction();
})

With this, you hold a boolean, canGo, and set it to true. If the function is run, it sets canGo to false and sets a setTimeout() for a time period of delay, in milliseconds. If you try to run the function again, it won't run and will, instead, alert("Can't go!"). This was just for demonstrative purposes; you don't need that part. After delay, canGo will be set to true, and you will be able to once more run the function.

var lastRan = 0;

var myFunction = function() {
  var now = Date.now();
  if(now-lastRan < 1000) {
      return;
  }

  lastRan = now;

  //rest of function
};

You may want to use throttle or debounce from underscore.js

http://underscorejs/#throttle

throttle_.throttle(function, wait, [options])

Creates and returns a new, throttled version of the passed function, that, when invoked repeatedly, will only actually call the original function at most once per every wait milliseconds. Useful for rate-limiting events that occur faster than you can keep up with.

By default, throttle will execute the function as soon as you call it for the first time, and, if you call it again any number of times during the wait period, as soon as that period is over. If you'd like to disable the leading-edge call, pass {leading: false}, and if you'd like to disable the execution on the trailing-edge, pass {trailing: false}.

var throttled = _.throttle(updatePosition, 100);
$(window).scroll(throttled);

http://underscorejs/#debounce

debounce_.debounce(function, wait, [immediate])

Creates and returns a new debounced version of the passed function which will postpone its execution until after wait milliseconds have elapsed since the last time it was invoked. Useful for implementing behavior that should only happen after the input has stopped arriving. For example: rendering a preview of a Markdown ment, recalculating a layout after the window has stopped being resized, and so on.

Pass true for the immediate parameter to cause debounce to trigger the function on the leading instead of the trailing edge of the wait interval. Useful in circumstances like preventing accidental double-clicks on a "submit" button from firing a second time.

var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);

If you just want to run your function again after a set time, you can use setTimeout and pass it the function to run and the delay period in milliseconds.

function myfunction() {
    //the function

    //run again in one second
    setTimeout(myfunction, 1000);
}

Edited based on poster's ments:

var waiting = false;

var myfunction = function() {
    if (!waiting) {
        //Run some code

        waiting = setTimeout(function() {
            waiting = false;
        }, 1000);
    }
};

本文标签: Wait before a javascript function can be called againStack Overflow