I have the following code:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<div id="logger"></div>
<script>
function log(txt) {
document.getElementById('logger').innerHTML += txt + '<br>';
}
var int = 10;
var a= setTimeout(function(){
a = null;
log("A fired!");
clearTimeout(b);
b = null;
}, int);
var b = setTimeout(function(){
b = null;
log("B fired!");
clearTimeout(a);
a = null;
}, int);
</script>
</body>
</html>
Both timeout callbacks should prevent another another one from firing. In Opera, FF and Chrome only first one (that prints ″A fired″) is executed. But when I run the same code in IE6 and IE8, both callbacks are executed. Is that some error in my scriupt or is that one of those bugs that these browsers are full of? Do clearTimeout()/clearInterval() guarantee that callback won’t be called after their invocation?
I think what is happening is that:
I suspect that in IE, the event gets queued and calling clearTimeout does not remove the event from the event queue.
It is also possible there is just funkyness in how IE pushes simultaneous timeouts onto the queue… Diagnosing the underlying cause could be acheived by using two different timeouts, using 100% CPU processing loops for x time, and by queuing/slotting in other events (maybe can inject events into queue using window.postMessage() and catch them with window.onMessage()).
I have modified your existing code to demonstrate the problem better. It queues the log items rather than doing them immediately, because calling display() can cause layout or rendering to occur, which can easily introduce other funky interference.
Edit: You can test this using http://jsbin.com/ucukez/2 – if the browser has the fault then you get “in A timeout fired” and “in B timeout fired”.
Edit: This was fixed in IE9 – I couldn’t reproduce in IE9/IE10/IE11.
The HTML is: