Today's programmatic venting is brought to you by Internet Explorer's implementation of the setTimeout() function under Javascript.
What is setTimeout()?
setTimeout() schedules an arbitrary function call for some point in future. This is useful when you have functions that do repetitive tasks some milliseconds apartment, but not constantly.
The reason why this is used instead of a simply while (true) { ... } loop is because Javascript is a single-threaded language. So if you tie up the interpreter by executing one piece of code over and over, nothing else in the browser gets a chance to run. setTimeout() allows other pieces of Javascript (or browser events, such as clicking on a button) to run, while guaranteeing that your code will be executed at some point.
Sounds cool. How do I use setTimeout()?
Simple, like this:
setTimeout(function_name, msec);
This will cause a function called function_name to execute a certain number of milliseconds in the future.
For functions that don't need data passed into them, that works great. But what if you want to pass in parameters? In FireFox, you would do this:
setTimeout(function_name, msec, arg1);
And this works great. It will call the function called function_name again in the specified number of milliseconds. Except, MSIE doesn't like this. And rather than throw an error, it just ignores the additional arguments. So when function_name gets called again, its argument is now undefined, and choas ensues.
[Edit: It has since been pointed out to me that the most recent draft of the spec does not allow for additional parameters to setTimeout(). Okay then, but why isn't MSIE at least throwing an error? Silently accepting additional arguments and then just throwing them away is just plain stupid.]
So how do I work around this annoyance?
Closures. Up until now, I thought that closures were very geeky, and used only by CS people who were working on their PhDs. Then I saw this:
setTimeout(function() {function_name(arg1)}, msec);
Wait, what? What's going on there? Well, it might be a little easier to understand if I write it like this:
var f = function() {function_name(arg1); };
setTimeout(f, msec);
What's happening there is a variable called "f" is created, which is actually an anonymous function. That function in turn contains a single line of code: function_name(arg1); -- a call to the function we really want to call, with our specified argument. Note that all we have done so far is define a function that calls our target function. We have not executed either that function or the target function -- the target function is essentially "frozen in time". This is a very important concept, and if you've never done this before, you will have difficulty wrapping your brain around it. :-)
To get a better idea of what's going on, in this case, you could also execute the variable f as a function, since it now *is* a function for all intents and purposes:
f();
Bringing this all together, in the above example, the end result is that the function function_name will be executed after the specified interval, with the desired argument. And this will work in both MSIE and FireFox.
Just out of curiosity, what is a practical application of this function?
I'm glad you asked! As I mentioned above, Javascript is single-threaded. This means that a loop that takes a long time to run can cause the browser to appear to "freeze up" or become unresponsive, which detracts from the overall user experience. A perfect example of this would be populating a div with rows of data retrieved via AJAX. Writing 1,000 rows into that div takes about 3.2 seconds on my machine, during which the browser will not respond to commands.
What I did in my little test was instead of printing each row as it was retrieved, I instead stored them in an array. I then wrote a function which shift()ed and printed only 50 elements from that array. After 50 elements were printed, it then checked to see if there were any elements left in the array. If there were, it would call setTimeout() with itself and the array inside a closure, to be run again in 10 millseconds. The end result took a little longer, 3.5 seconds, but resulted in a much more responsive browser, and happier users.
Share and enjoy!
Source: Passing parameters to a function called with setTimeout, by Bryan Gullen
What is setTimeout()?
setTimeout() schedules an arbitrary function call for some point in future. This is useful when you have functions that do repetitive tasks some milliseconds apartment, but not constantly.
The reason why this is used instead of a simply while (true) { ... } loop is because Javascript is a single-threaded language. So if you tie up the interpreter by executing one piece of code over and over, nothing else in the browser gets a chance to run. setTimeout() allows other pieces of Javascript (or browser events, such as clicking on a button) to run, while guaranteeing that your code will be executed at some point.
Sounds cool. How do I use setTimeout()?
Simple, like this:
setTimeout(function_name, msec);
This will cause a function called function_name to execute a certain number of milliseconds in the future.
For functions that don't need data passed into them, that works great. But what if you want to pass in parameters? In FireFox, you would do this:
setTimeout(function_name, msec, arg1);
And this works great. It will call the function called function_name again in the specified number of milliseconds. Except, MSIE doesn't like this. And rather than throw an error, it just ignores the additional arguments. So when function_name gets called again, its argument is now undefined, and choas ensues.
[Edit: It has since been pointed out to me that the most recent draft of the spec does not allow for additional parameters to setTimeout(). Okay then, but why isn't MSIE at least throwing an error? Silently accepting additional arguments and then just throwing them away is just plain stupid.]
So how do I work around this annoyance?
Closures. Up until now, I thought that closures were very geeky, and used only by CS people who were working on their PhDs. Then I saw this:
setTimeout(function() {function_name(arg1)}, msec);
Wait, what? What's going on there? Well, it might be a little easier to understand if I write it like this:
var f = function() {function_name(arg1); };
setTimeout(f, msec);
What's happening there is a variable called "f" is created, which is actually an anonymous function. That function in turn contains a single line of code: function_name(arg1); -- a call to the function we really want to call, with our specified argument. Note that all we have done so far is define a function that calls our target function. We have not executed either that function or the target function -- the target function is essentially "frozen in time". This is a very important concept, and if you've never done this before, you will have difficulty wrapping your brain around it. :-)
To get a better idea of what's going on, in this case, you could also execute the variable f as a function, since it now *is* a function for all intents and purposes:
f();
Bringing this all together, in the above example, the end result is that the function function_name will be executed after the specified interval, with the desired argument. And this will work in both MSIE and FireFox.
Just out of curiosity, what is a practical application of this function?
I'm glad you asked! As I mentioned above, Javascript is single-threaded. This means that a loop that takes a long time to run can cause the browser to appear to "freeze up" or become unresponsive, which detracts from the overall user experience. A perfect example of this would be populating a div with rows of data retrieved via AJAX. Writing 1,000 rows into that div takes about 3.2 seconds on my machine, during which the browser will not respond to commands.
What I did in my little test was instead of printing each row as it was retrieved, I instead stored them in an array. I then wrote a function which shift()ed and printed only 50 elements from that array. After 50 elements were printed, it then checked to see if there were any elements left in the array. If there were, it would call setTimeout() with itself and the array inside a closure, to be run again in 10 millseconds. The end result took a little longer, 3.5 seconds, but resulted in a much more responsive browser, and happier users.
Share and enjoy!
Source: Passing parameters to a function called with setTimeout, by Bryan Gullen

