Problem

Timeout functions are not accurate. They are not guaranteed to fire at the exact time you set them to. This is because the browser is busy doing other things. The browser is not guaranteed to be idle at the exact time you set the timeout. This is why you can’t rely on the timeout to fire at the exact time you set it to.

We can schedule calls in Javascript using the following methods:

  • setTimeout allows us to run a function once after the interval of time.
  • setInterval allows us to run a function repeatedly, starting after the interval of time, then repeating continuously at that interval.

These methods are not a part of JavaScript specification. But most environments have an internal scheduler and provide these methods. In particular, they are supported in all browsers and Node.js.

setTimeout example
let timeoutId = setTimeout(func, delay, [arg1], [arg2])

Adding Precision to setTimeout methods.

This is a more precise version of the native setTimeout(). It uses the same parameters as setTimeout, but adds a third parameter “resolution” which defines how often (in ms) to check for the time that passed. Sometimes we might need to schedule tasks with some precision then we can write following function

const setExactTimeout = function(callback, duration, resolution) {
	const start = (new Date()).getTime();
	const timeout = setInterval(function(){
		if ((new Date()).getTime() - start > duration) {
			callback();
			clearInterval(timeout);
		}
	}, resolution);

	return timeout;
};

const clearExactTimeout = function(timeout) {
	clearInterval(timeout);
};

We can implement it with the third argument as follow:

// alert after 5 seconds with an inaccuracy of 20 milliseconds
var timeout = setExactTimeout(function(){
   alert('done');
}, 5000, 20);

// comment out to show "done"
clearExactTimeout(timeout);