JavaScript – Using setInterval and setTimeout

In javascript, the two functions setInterval and setTimeout can be extremely useful and important, but using either of them in complex ways can be a confusing ordeal. In this tutorial, I’m going to try and show the range of possibilities, from the very simple, to the complex, to the ‘why oh why is it working like this!?’.

So lets start out with the extremely simple – what do the setInterval and setTimeout functions do? They are both functions attached to the window object of a web page, and they allow, in a very crude manner, a sort of ‘thread-like’ control.

setTimeout – The setTimeout function delays for a specified time period and then riggers execution of a specified function. Once the function is triggered the setTimeout has finished. You can of course terminate the execution of the setTimeout before it triggers the function by using the clearTimeout function.

setInterval – The setInterval function also delays for a specified time before triggering the execution of a specific function. Where it differs is that after triggering that function the command doesn’t complete. Instead it waits for the specified time again and then triggers the function again and continues to repeat this process of triggering the function at the specified intervals until either the web page is unloaded or the clearInterval function is called.

The setTimeout call lets you tell the browser to execute a javascript call after a certain time has passed. It takes two arguments – what to execute, and how long to wait (in milliseconds). Here is an example of a very simple setTimeout call:

1

setTimeout("alert('hi!');",500);

This call will execute the code alert('hi!'); after 500 milliseconds has passed.

The setInterval call has similar arguments, but instead of just executing the given code once, it executes it over and over again, using the second argument as the amount of time to wait between executions. Here is a simple example of a setInterval call:

1

setInterval("alert('hi!');",500);

This call will execute the code alert('hi'); every 500 milliseconds from now until the the page it is loaded on is closed.

But if that was all you could do with these two functions, it wouldn’t be very interesting, now, would it? Fortunately, that is only the tip of the iceberg.

Both of these functions return an integer id when they are called – which in and of itself is not very useful. But what these ids allow you to do is clear an interval/timeout call if you don’t want it anymore. There are two companion funtions called clearTimeout and clearInterval which you can pass these ids to – and they will clear the timeout/interval associated with the id. This especially useful for setInterval, because it is probably rare that you want something on your page executing every X milliseconds for the entire time the user has the page open.

Using the functions is very simple, you can just call them like the following:

1

2

3

4

vartimeoutID=setTimeout("alert('hi!');",500);

varintervalID=setInterval("alert('hi!');",500);

clearTimeout(timeoutID);

clearInterval(intervalID);

Granted, that code is kind of silly, because the end result is that nothing will happen (neither the timout or the interval will ever get called). But it shows exactly how to use the clear functions.

An important thing to note about the first argument to both these functions is that they can either take a string or a function reference. A string is what we have been using so far, so lets continue to push on that technique, and I will talk about passing a function reference later.

When a string is passed to these functions, it is evaluated at the time of execution. What this means is that you can pack any kind of valid javascript in the string and it will “get run”. For example:

1

2

3

4

setTimeout("var foo = 2 + 2; alert(foo);",500);

setTimeout("var abc = 2 + bar; alert(abc);",500);

varbar=7;

The first call will cause a pop up with the value 4 to appear after 500 milliseconds. The second call will cause a pop up with the value 9 to appear, also after 500 milliseconds. The first example should make sense, but the second one can be a bit confusing. The reason it works, even though the variable bar was undefined when the setTimeout call was made, is that the contents of that string are not evaluated until after the 500 milliseconds are up. Since at that point, bar does exist, it can evaluate 2 + bar, and come up with 9.

An important thing to note is in what scope these strings are evaluated. They are evaluated in the global scope, so any variables or functions not accessible from the global scope will be undefined when the time comes for the string to be executed. For example:

1

2

3

4

5

6

7

functionfoo()

{

vari="hello";

setTimeout("alert(i);",500);

}

foo();

Instead of popping up the string “hello” after 500 milliseconds, there will be a javascript error saying that i is undefined. This is because i only existed inside the scope of the function foo – and the alert call is executed in the global scope. A place where this often catches people by surprise is inside objects – because the scope changes, the this reference is not maintained:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

functionfoo()

{

this.val="hi";

this.bar=function()

{

alert(this.val);

}

this.abc=function()

{

setTimeout("this.bar();",500);

}

}

varobj=newfoo();

obj.abc();

When the string here is evaluated in the context of the global scope, the this reference resolves to the window object – which means that this.bar will be undefined, and throw a javascript error. So whenever passing a string to setInterval/setTimeout, you need to be careful that any variables you are referencing will actually exist when the string gets evaluated and executed.

Ok, so thats about it for handing either of these functions a string to evaluate – lets move on to function references. First, a simple example:

1

2

3

4

5

6

functionfoo()

{

alert("hi!");

}

setTimeout(foo,500);

It should be pretty easy to see what this code would result in – the function foo will be called after 500 milliseconds.

In general, it is much easier to think about this method of using setInterval and setTimeout, because you don’t have to worry quite as much about who will evaluate to what at execution time. But it does have a significant drawback – there is no way to pass any arguments to the function you want called. Actually, that is not quite true – for Firefox, you actually can, but since you can’t do it in both major browsers, I’m not going to go into detail on it here (see the setTimeout and setInterval documentation if you want details on how to do it). But, guess what? There is a way to get around this drawback (most of the time):

1

2

3

4

5

6

7

8

9

10

11

12

functionfoo(i)

{

functionbar()

{

alert(i);

}

setTimeout(bar,500);

}

foo(5);

This code will cause a pop up to show the value 5 – and it is all because of the concept of function references and scope. Since we are now passing an actual function reference instead of a string, we get the added benefit of maintaining the scope of the function (instead of the assumption of global scope). The variable i here existed in the scope of the function bar – so when bar was finally evaluated, the variable i still existed.

This is actually a way to get around the fact that the this reference is never maintained with setInterval and setTimeout. Since the functions maintain their proper scope, we now have the ability to do things like:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

functionfoo()

{

varinternalVal=5;

functiontimoutFunc()

{

alert(internalVal);

}

this.setVal=function(val)

{

internalVal=val;

}

this.causeTimeout=function()

{

setTimeout(timoutFunc,500);

}

}

varobj=newfoo();

obj.causeTimeout();

obj.setVal(9);

This code will alert the value 9 – because while the this reference might not be maintained, the scope of the function timeoutFunc is, and so it knows where the get the variable internalVal.

I hope you found this tutorial helpful, and that you now have a better understanding of how and when to use the setTimeout and setInterval functions. If you have any questions, comments, or crazy ideas about these functions, please leave a comment.