setTimeout vs. setInterval

von

setTimeout and setInterval are to two Javscript core functions which invoke a function after a defined delay. But what is the difference? This article presents a comparsion of the functions by studying the output of an example program.

The program uses a function to produce a workload by calling n-times a product of four random numbers:

function workload(n) {
  while(n > 0) {
     Math.random()*Math.random()*Math.random()*Math.random();
     n-=1;
  }
}      

Every runtime without the call of workload is neglected. So the run time of functions calling workload is the runtime of the call of workload itself. The start and end time of the workload is measured by the wrapper function logWorkload:

var start = timestamp(); // start time

function logWorkload(label, run, n) {
  var t1 = timestamp() - start;
  workload(n);
  var t2 = timestamp() - start;
  console.log(label+' ('+run+') start: '+t1+' end:'+t2);
}

function timestamp() {
  return new Date().getTime();
}

The global variable start keeps the start time of the test program. All times measured by logWorkload are relative to the start time of the test program. The behaviour of setInterval is discovered by the following code:

var k = 0;
var tda = setInterval(function() {
  k+=1;
  if (k==3) {
    clearInterval(tda);
  }  
  logWorkload('setInterval', k, 500000);
}, 100); // delay

setInteval calls the anonymous function in the first parameter. The delay of 100ms is given as second parameter. The setInterval and setTimeout functions start a timer, who is responsible for the invocation of the function after the given delay. To control the timer both functions return a timerid. In this example the timerid is stored in the global variable tda. The number of invocations are counted by the global variable k. If the anonymous function is called the third time, its timer is cleared by clearInterval. clearInterval takes therefore the timerid as parameter simply. The output is as follows:

setInterval (1) start: 100 end:123
setInterval (2) start: 200 end:227
setInterval (3) start: 300 end:326

setInterval calls the anonymous function periodically every 100ms, starting with a delay. The runtime of the anonymous function, around 25ms, is neglected. A periodically invocation of a function can be done by setTimout also:

var kk = 0;
function set() {
  kk+=1;
  logWorkload('setTimeout', kk, 1000000);
  if (kk<6) {
    setTimeout(set, 100);
  }
}
set();

set invokes itself recursive by call of setTimeout with a delay of 100ms. The output is as follows:

setTimeout (1) start: 0 end:58
setTimeout (2) start: 158 end:215
setTimeout (3) start: 325 end:393
setTimeout (4) start: 494 end:554
setTimeout (5) start: 874 end:1022
setTimeout (6) start: 1122 end:1179

The first call of set is done synchrony, without a delay. The second call starts after a delay of 100ms. But the runtime of around 60ms before reaching the setTimeout expression has to be added. So setTimeout is not exactly periodical like setInterval, but if the program breaks before the next setTimeout expression is reached, it stops! setInterval won't stop trying. If both programs are combined this output results:

setTimeout (1) start: 0 end:59 
setInterval (1) start: 100 end:125
setTimeout (2) start: 159 end:222
setInterval (2) start: 222 end:290
setTimeout (3) start: 322 end:382
setInterval (3) start: 382 end:406
setTimeout (4) start: 482 end:546
setTimeout (5) start: 647 end:704
setTimeout (6) start: 804 end:865

The first call of setIntervall starts after a delay of 100ms regular. The second call of set starts at 159ms exactly 100 ms after the end of the first call. The second invocation of the anonymous function by setIntervall can not start after 200ms, cause the second call of setTimeout is still running. All Javascript in browsers are executed by a single thread. So asynchronus function calls, e.g. setInterval, setTimeout or invoked by any event listener, can be executed serial only.

setTimeout and setInterval invoke functions after a delay. setInterval repeat the invocation periodically, as far as possible. Beware of setInterval, cause the invocation won't stop if an error occurs in the invoked function. setTimerout can do also a periodically invocation, but the runtime of code has to be added. But if the program aborts, before the next setTimeout call is reached no additional invocations takes place.