You miss one key feature of the JavaScript internal structure: The event loop. All functions get stored there and wait until they get executed. Furthermore, JavaScript (in general - leaving out AJAX and workers) is single threaded, so at any time, just one function gets executed.
With respect to your script: The first function on the event queue is your ready()
callback. It gets executed and while doing so places many other functions (the callbacks from the setTimeout()
call) on the event queue. But in order to execute those, the first function has to be finished, meaning all the loop has to be done and the function has to return.
So basically this happens (the second row in each bullet point denotes the current event loop state):
Just the ready
callback is queued for execution.
ready()-callback
The setTimeout()
callback gets placed on the event queue.
ready()-callback | setTimeout()-callback
All the looping is done.
ready()-callback | setTimeout()-callback
The ready()
callback has finished and is removed from the queue.
setTimeout()-callback
Just now the setTimeout()
callback is executed and you see your alert()
message!
setTimeout()-callback
So in order to get your alert()
somewhere in between the loop execution, you either have to execute it after, e.g., the 2500th iteration:
$(document).ready(function(){
var k = 0;
for (var i = 0; i < 5000; ++i) {
++k;
$('.inner').append('<p>Test</p>' + k.toString());
if( i == 2500 ) {
alert( 'Hello' );
}
}
});
Or put all those inserts in setTimeout()
callbacks too (which require some kind of closure, if you want to access the outside k
):
$(document).ready(function(){
var k = 0;
setTimeout(function(){alert("Hello")},500);
for (var i = 0; i < 5000; ++i) {
++k;
setTimeout( (function( k ) {
$('.inner').append('<p>Test</p>' + k.toString());
})( k ), 0 );
}
});