Jake Doesn't Always Know Best. Do You?
I got bitten yesterday by my own stupidity, while trying to "improve" some code I'd inherited as part of an app.
The code looked something like this, in essence:
function callRepeatedly(){ document.getElementById("updateMe").innerHTML= new Date().toString(); } function callOnce(){ callRepeatedly(); window.setInterval("callRepeatedly()", 5000); } window.onload = callOnce
You can probably work out that the page it lives on has an element's HTML updated every five seconds to the current time. Pointless I know, but stick with it.
Always thinking I know better I looked at the code and thought I'd make it simpler by removing the callOnce() function, which seemed redundant to me.
My re-factored code looked like:
function callRepeatedly(){ document.getElementById("updateMe").innerHTML= new Date().toString(); window.setInterval("callRepeatedly()", 5000); } window.onload = callRepeatedly
This shorter bit of code did the same thing and less code is always a better thing, right? When the page loaded the element got updated and a "time out" was set to do the same every five seconds.
I made the change and thought nothing more of it. That's when the issues began. The website starting hanging the browser (100% CPU leading to forced closing of the task!) if the browser was left standing for more than about 10 minutes.
At first I had no idea what was causing this and it took me hours and hours to work out it was because of the "improvement" I had made to the above code.
Can you see what was causing the browser to crash? Top prize to anybody who can!
It sounds like recursion. Each 5 seconds you schedule a new call.
Well you seem to be calling callRepeatedly recursivly .with no exit point..bound to crash... right?
You have done a mistake here: window.setInterval("callRepeatedly()", 5000);
Should be:
window.setTimeout("callRepeatedly()", 5000);
Otherwise you have doubling timeouts every 5 seconds.
Where is my prize???
You're creating a "chain reaction" of intervals..
First there is one. Five seconds later, there is two, five seconds more there is four....
My guess is that you didn't notice the 'setInterval' and expected 'setTimeout' behaviour
Ok, ok. You all get the prize of a collective pat on the back. I feel even more stupid know. Thought it would take you a bit longer than that.
You all got it right, but Thimo picked up on the reason why it happened. Until yesterday I didn't realise that setInterval existed. I'd read that line of code and my mind must have seen "setTimeout" and that's how I thought the code worked. Not being aware of the difference between the two methods I wasn't to know the devastating effect it would reak. Glad I caught it in development mode.
You live and learn. Lesson yesterday was - if it ain't broke, don't fix it.
We call it experience. But it's only collection of mistakes. We all have our own bag. The trick is to fill the bag of mistakes, before the bag of luck runs empty.
Thats a really good example of a negative pattern - one that takes a few minutes to manifest.
nice!
(And yes, you get an exponentially increasing number of instances of your function every five seconds)
--* Bill