Skip to main content

JavaScript Timer-Based Pseudo-Threading

By Craig Buckler



Free JavaScript Book!

Write powerful, clean and maintainable JavaScript.

RRP $11.95

In my previous post, JavaScript Execution and Browser Limits, I described how the top 5 browsers determine when JavaScript code has run for too long and throw “unresponsive script” errors. It’s not practical to change the browser’s behavior and it may not always be possible to offload processing to the server. Fortunately, timers can help us execute long-running tasks without locking the browser.

What are timers?

JavaScript code, such as an individual function, can be set to run after a particular period of time has elapsed:

  • setTimeout(function, msec[, arg1 … argN])
    runs the named function after msec milliseconds have passed. The arguments, if any, are passed to that function.
  • setInterval(function, msec[, arg1 … argN])
    is similar to setTimeout except the function is called indefinitely every msec milliseconds.

Two other functions, clearTimeout() and clearInterval(), will cancel timer operations, e.g.

var timerID = setTimeout(myfunction, 500);
clearTimeout(timerID); // myfunction() will never be called


  1. setTimeout and setInterval are passed a reference to a function (there’s no parenthesis). The code setTimeout(myfunction(), 500); would run myfunction() immediately.
  2. The millisecond timings will rarely be accurate. They only specify that a function should run when the browser becomes idle after a specific period.
  3. Don’t rely on functions running in a specific order, e.g. setTimeout(f1, 50); setTimeout(f2, 50); — f2() could execute first.

Timer-based execution

Timed code isn’t run immediately, so the browser processing thread is released to perform other tasks. We can therefore split long processes into shorter chunks.

As a simple example, assume we want to run the functions f1(), f2() and f3() in order:

function ProcessThread(func) {
	var ms = 20;
	setTimeout(function() {
		if (func) {
			setTimeout(arguments.callee, ms);
	}, ms);

ProcessThread([f1, f2, f3]);
note: func.shift()() ?!

That requires a little further explanation; func.shift() removes the first item from an array and returns it. That will be reference to a function, so we add parenthesis to execute it.

The statement is functionally identical to var f = func.shift(); f();

ProcessThread runs all the functions in the passed array, but waits 20ms between each. Any number of functions can be executed in sequence … assuming no individual function throws an “unresponsive script” error.

However, the most time-intensive code will probably be processing large arrays of data. In my next post, we’ll write more robust code to handle that type of operation.

Craig is a freelance UK web consultant who built his first page for IE2.0 in 1995. Since that time he's been advocating standards, accessibility, and best-practice HTML5 techniques. He's created enterprise specifications, websites and online applications for companies and organisations including the UK Parliament, the European Parliament, the Department of Energy & Climate Change, Microsoft, and more. He's written more than 1,000 articles for SitePoint and you can find him @craigbuckler.

New books out now!

Get practical advice to start your career in programming!

Master complex transitions, transformations and animations in CSS!

Latest Remote Jobs