相关文章推荐
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Using setTimeout() it is possible to launch a function at a specified time:

setTimeout(function, 60000);

But what if I would like to launch the function multiple times? Every time a time interval passes, I would like to execute the function (every 60 seconds, let's say).

If you don't care if the code within the timer may take longer than your interval, use setInterval():

setInterval(function, delay)

That fires the function passed in as first parameter over and over.

A better approach is, to use setTimeout along with a self-executing anonymous function:

(function(){
    // do some stuff
    setTimeout(arguments.callee, 60000);
})();

that guarantees, that the next call is not made before your code was executed. I used arguments.callee in this example as function reference. It's a better way to give the function a name and call that within setTimeout because arguments.callee is deprecated in ecmascript 5.

It's not possible for the next call to be made before the code finishes executing. The timer counts down asynchronously but the callback has to be queued. This means that your callback may (and probably will) fire after more than 60 seconds. – Andy E Jun 29, 2010 at 7:52 The difference is that setInterval will generally run the function x milliseconds after the start of the previous iteration, whereas the approach here will run the next iteration x milliseconds after the previous one ended – Gareth Jun 29, 2010 at 8:14 Just as a note for others who may find this -- clearInterval() is a partner function to setInterval() and comes in handy if you want to cease your periodic function call. – Clay Sep 15, 2011 at 14:15 Please note that setInterval executes the function for the first time after delay ms. So if you want to execute function immediately, and THEN repeat every delay, you should do: func(); setInterval(func, delay); – Marco Marsala Aug 6, 2014 at 10:48 I just don't get this arguments.callee thing. I have getRates() function but (function(){getRates(); setTimeout(getRates(), 10000); })(); is not working :/ – darth0s Nov 8, 2017 at 15:51

A better use of jAndy's answer to implement a polling function that polls every interval seconds, and ends after timeout seconds.

function pollFunc(fn, timeout, interval) {
    var startTime = (new Date()).getTime();
    interval = interval || 1000;
    (function p() {
        fn();
        if (((new Date).getTime() - startTime ) <= timeout)  {
            setTimeout(p, interval);
    })();
pollFunc(sendHeartBeat, 60000, 1000);

UPDATE

As per the comment, updating it for the ability of the passed function to stop the polling:

function pollFunc(fn, timeout, interval) {
    var startTime = (new Date()).getTime();
    interval = interval || 1000,
    canPoll = true;
    (function p() {
        canPoll = ((new Date).getTime() - startTime ) <= timeout;
        if (!fn() && canPoll)  { // ensures the function exucutes
            setTimeout(p, interval);
    })();
pollFunc(sendHeartBeat, 60000, 1000);
function sendHeartBeat(params) {
    if (receivedData) {
        // no need to execute further
        return true; // or false, change the IIFE inside condition accordingly.
                This is good example! When you use timers it harder to write unit tests, but with this approach - it's easy
– Dmytro Medvid
                Sep 5, 2016 at 17:18
                Good answer. Please could you update one of the uses of new Date so that they are consistent, one uses (new Date).getTime() and the other (new Date()).getTime(). Both seem to work ok though
– Mark Adamson
                Mar 7, 2018 at 11:45
       /// call your function here
      random_no();
}, 6000);  // Change Interval here to test. For eg: 5000 for 5 sec
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="random_no_container">
      Hello. Here you can see random numbers after every 6 sec
                see comment // Change Interval here to test. For eg: 5000 for 5 sec Currently it is set to change every 6 seconds. use value 60000 for a minute
– Optimum Creative
                Aug 4, 2017 at 7:39

You can simply call setTimeout at the end of the function. This will add it again to the event queue. You can use any kind of logic to vary the delay values. For example,

function multiStep() {
  // do some work here
  blah_blah_whatever();
  var newtime = 60000;
  if (!requestStop) {
    setTimeout(multiStep, newtime);

A good example where to subscribe a setInterval(), and use a clearInterval() to stop the forever loop:

function myTimer() {
var timer = setInterval(myTimer, 5000);

call this line to stop the loop:

clearInterval(timer);
var intervalPromise;
$scope.startTimer = function(fn, delay, timeoutTime) {
    intervalPromise = $interval(function() {
        fn();
        var currentTime = new Date().getTime() - $scope.startTime;
        if (currentTime > timeoutTime){
            $interval.cancel(intervalPromise);
    }, delay);
$scope.startTimer(hello, 2000, 10000);
hello(){
  console.log("hello");
setInterval(() => {
    const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';//rgb value (0-255,0-255,0-255)
    document.body.style.backgroundColor = rndCol;   
}, 1000);
<script src="test.js"></script>
it changes background color in every 1 second (written as 1000 in JS)
// checkEach(1000, () => { // if(!canIDoWorkNow()) { // return true // try again after 1 second // } // doWork() // }) export function checkEach(milliseconds, fn) { const timer = setInterval( () => { try { const retry = fn() if (retry !== true) { clearInterval(timer) } catch (e) { clearInterval(timer) throw e milliseconds

here we console natural number 0 to ......n (next number print in console every 60 sec.) , using setInterval()

var count = 0;
function abc(){
    count ++;
    console.log(count);
setInterval(abc,60*1000);

I see that it wasn't mentioned here if you need to pass a parameter to your function on repeat setTimeout(myFunc(myVal), 60000); will cause an error of calling function before the previous call is completed.

Therefore, you can pass the parameter like

setTimeout(function () {
            myFunc(myVal);
        }, 60000)

For more detailed information you can see the JavaScript garden.

Hope it helps somebody.

I favour calling a function that contains a loop function that calls a setTimeout on itself at regular intervals.

function timer(interval = 1000) {
  function loop(count = 1) {
    console.log(count);
    setTimeout(loop, interval, ++count);
  loop();
timer();
 
推荐文章