One crucial aspect of the internal structure of JavaScript is the event loop. All functions are stored there and wait for execution. JavaScript, in general (excluding AJAX and workers), operates on a single thread, meaning only one function is executed at a time.
Regarding your script: The first function in the event queue is your ready()
callback. It executes and in the process, adds many other functions (the callbacks from the setTimeout()
call) to the event queue. However, in order for those functions to execute, the first function must complete, which requires the loop to finish and the function to return.
Here is a breakdown of what occurs (the second row in each bullet point represents the current event loop state):
Only the ready
callback is queued for execution.
ready()-callback
The setTimeout()
callback is added to the event queue.
ready()-callback | setTimeout()-callback
The looping is completed.
ready()-callback | setTimeout()-callback
The ready()
callback finishes and is removed from the queue.
setTimeout()-callback
The setTimeout()
callback is now executed, displaying your alert()
message!
setTimeout()-callback
To have your alert()
appear in between loop executions, you can execute it after a certain iteration, for example, after 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' );
}
}
});
Alternatively, you can place all those inserts in setTimeout()
callbacks as well (this requires some form of closure if you need to access the external variable 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 );
}
});