你忽略了 JavaScript 内部结构中一个重要的特征:事件循环。所有函数都存储在那里等待执行。此外,JavaScript(一般情况下 - 不包括 AJAX 和 workers)是单线程的,因此任何时候只能执行一个函数。
对于你的脚本:事件队列中的第一个函数是你的 ready() 回调。它被执行并在执行时将许多其他函数(来自 setTimeout() 调用的回调)放置在事件队列中。但是为了执行这些函数,第一个函数必须完成,也就是说整个循环必须完成并且函数必须返回。
所以基本上会发生以下情况(每个项目的第二行表示当前事件循环状态):
1. 只有 ready 回调排队等待执行。
ready()-callback
2. setTimeout 回调被放置在事件队列中。
ready()-callback | setTimeout()-callback
3. 所有循环都完成了。
ready()-callback | setTimeout()-callback
4. ready() 回调已经完成并从队列中删除。
setTimeout()-callback
5. 现在执行 setTimeout() 回调并看到你的 alert() 消息!
setTimeout()-callback
因此,为了在循环执行之间的某个时间获得 alert(),您需要在第2500次迭代之后执行它。
$(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' );
}
}
});
或者将所有这些插入项也放在setTimeout()
回调中(如果想要访问外部的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 );
}
});