304

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).

Samuel Liew
  • 76,741
  • 107
  • 159
  • 260
Richard Knop
  • 81,041
  • 149
  • 392
  • 552
  • Does this answer your question? [JavaScript: get code to run every minute](https://stackoverflow.com/questions/13304471/javascript-get-code-to-run-every-minute) – Nakilon Mar 21 '23 at 00:45

15 Answers15

440

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.

Edric
  • 24,639
  • 13
  • 81
  • 91
jAndy
  • 231,737
  • 57
  • 305
  • 359
  • 6
    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 '10 at 07:52
  • 18
    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 '10 at 08:14
  • 1
    @Andy E's head, @Gareth: Gareth is right, that approach just avoids that loop-code will executed while another codeblock is still running. – jAndy Jun 29 '10 at 08:20
  • True enough, you edited your answer after I wrote/while I was writing my comment. What I said still stands though, there's no danger of the next callback executing before the previous one has finished. – Andy E Jun 29 '10 at 13:55
  • 47
    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 '11 at 14:15
  • 7
    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 06 '14 at 10:48
  • 1
    Just to make it clear.. You should chose to use setInterval if the exact time will mater more then the possible function overlapings. In case you just want to keep a gap of 60 seckounds (+ what ever it takes to execute the function) then it would be better to use setTimeout inside recursive function with an "if" statment... so you can switch it of when ever you wish to. Something like: if(globalvar == true){setTimeout(.....,60000)}, than all you have to do to stop it to set the globalvar to false – DevWL Mar 18 '16 at 01:03
  • 5
    I just don't get this arguments.callee thing. I have getRates() function but (function(){getRates(); setTimeout(getRates(), 10000); })(); is not working :/ – darth0s Nov 08 '17 at 15:51
  • Wouldn't that just call the function one time after 6 seconds? ``` (function() { const doIt = () => { console.log('do it!') } setTimeout(doIt, 5000) })() // waits 6 seconds and logs 'do it' one time. ``` Clearly I am misunderstanding the answer as it is accepted with well over 300 upvotes. Can someone please fill me in? Thanks! – Neil Girardi Jul 28 '20 at 21:34
  • `arguments.callee` is not deprecated and should not be used. – Heretic Monkey Jan 21 '22 at 13:03
  • @HereticMonkey Your comment is somewhat confusing. Should it read *"`arguments.callee` is **now** deprecated and should not be used."* or *"`arguments.callee` is not deprecated and should **be** used."* or maybe *"`arguments.callee` is not deprecated **but don't use it**."*? – Jonny Henly Jan 11 '23 at 18:34
  • 1
    @JonnyHenly Typo... Should read "now", as you surmised. – Heretic Monkey Jan 11 '23 at 20:08
81

use the

setInterval(function, 60000);

EDIT : (In case if you want to stop the clock after it is started)

Script section

<script>
var int=self.setInterval(function, 60000);
</script>

and HTML Code

<!-- Stop Button -->
<a href="#" onclick="window.clearInterval(int);return false;">Stop</a>
Muneer
  • 7,384
  • 7
  • 38
  • 62
27

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.
    }
}
Community
  • 1
  • 1
Om Shankar
  • 7,989
  • 4
  • 34
  • 54
22

In jQuery you can do like this.

function random_no(){
     var ran=Math.random();
     jQuery('#random_no_container').html(ran);
}
           
window.setInterval(function(){
       /// 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
</div>
azro
  • 53,056
  • 7
  • 34
  • 70
Optimum Creative
  • 1,438
  • 13
  • 21
  • The number renews more or less every 12 seconds - shouldn't this be one minute? – Max Aug 03 '17 at 20:55
  • 2
    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 04 '17 at 07:39
9
setInterval(fn,time)

is the method you're after.

Jamiec
  • 133,658
  • 13
  • 134
  • 193
9

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);
  }
}
John Henckel
  • 10,274
  • 3
  • 79
  • 79
7

Use window.setInterval(func, time).

Oleg V. Volkov
  • 21,719
  • 4
  • 44
  • 68
6

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);
turivishal
  • 34,368
  • 7
  • 36
  • 59
4

Call a Javascript function every 2 second continuously for 10 second.

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");
}
Ankit Tiwari
  • 41
  • 2
  • 6
2

function random(number) {
  return Math.floor(Math.random() * (number+1));
}
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)
user12449933
  • 170
  • 1
  • 6
1
// example:
// 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
  )
}
srghma
  • 4,770
  • 2
  • 38
  • 54
1

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);
turivishal
  • 34,368
  • 7
  • 36
  • 59
Vijay sadhu
  • 500
  • 4
  • 11
1

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.

Taylan Yuksel
  • 345
  • 3
  • 12
0

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();
Andy
  • 61,948
  • 13
  • 68
  • 95
-1

There are 2 ways to call-

  1. setInterval(function (){ functionName();}, 60000);

  2. setInterval(functionName, 60000);

above function will call on every 60 seconds.

Shahzad Barkati
  • 2,532
  • 6
  • 25
  • 33
Gaurav Tripathi
  • 1,265
  • 16
  • 20