scratched tallies on the prison wall

Everyone’s written a JavaScript loop that just loops over all the {LIs,
links, divs} on a
page\*,
and it’s pretty standard. Something like
var lis = document.getElementsByTagName(“li”);
for (var i=0; i
or, if you’re using jQuery:
$(“li”).each(function() {
// do something here to this
});

This is problematic if there are, say, 2000 LI elements on the page, and
what you’re doing in the loop is semi-intensive (imagine you’re creating
a couple of extra elements to append to each of those LIs, or something
like that). The reason this is a problem is that JavaScript is
single-threaded. A tight loop like this hangs the browser until it’s
finished, you get the “this script has been running for a long time”
dialog, and the user interface doesn’t update while you’re in this kind
of loop. You might think: aha, this will take a long time, so I’ll have
some sort of a progress monitor thing:
var lis = document.getElementsByTagName(“li”);
for (var i=0; i
but that doesn’t work. What happens is that the browser freezes until
the loop finishes. Annoying, but there it is. One approach to getting
around this is with timeouts rather than a `for` loop.
var lis = document.getElementsByTagName(“li”);
var counter = 0;
function doWork() {
// do something here to lis[i]
counter += 1;
progressMonitor.innerHTML = “processing list item ” + counter;
if (counter < lis.length) {
setTimeout(doWork, 1);
}
};
setTimeout(doWork, 1);

and now you can do
$.eachCallback(someArray, function() {
// “this” is the array item, just like $.each
}, function(loopcount) {
// here you get to do some UI updating
// loopcount is how far into the loop you are
});
$(“li”).eachCallback(function() {
// do something to this
}, function(loopcount) {
// update the UI
});
Not always a useful technique, but when you need it, you need it.