我在jQuery上做了以下程序:
$(document).ready(function(){
var k = 0;
setTimeout(function(){alert("Hello")},500);
for (var i = 0; i < 5000; ++i) {
++k;
$('.inner').append('<p>Test</p>' + k.toString());
}
});我预计计时器事件将在循环执行期间执行警告"Hello“字符串的函数。然而,它只在循环结束后发生。
是不是语言特定的问题?在某些循环/执行中,我应该如何实现回调函数处理?
发布于 2013-05-26 16:42:14
您忽略了JavaScript内部结构的一个关键特性:事件循环。所有的函数都存储在那里,并等待它们被执行。此外,JavaScript (通常不包括AJAX和workers)是单线程的,所以在任何时候,只执行一个函数。
关于您的脚本:事件队列上的第一个函数是您的ready()回调。它被执行,同时将许多其他函数(来自setTimeout()调用的回调)放在事件队列中。但是为了执行这些函数,第一个函数必须完成,这意味着所有的循环都必须完成,函数必须返回。
因此,基本上会发生这种情况(每个项目符号中的第二行表示当前事件循环状态):
ready回调被排队等待执行。ready()-callback
setTimeout()回调放到事件队列中。setTimeout()-callback ()-callback|ready
setTimeout()-callback ()-callback|ready
ready()回调已完成并从队列中删除。setTimeout()-callback
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 );
}
});发布于 2013-05-26 16:45:20
是的,这是一个语言问题。JavaScript中的setTimeout在指定的毫秒数后执行代码,在本例中为500。它将脚本排入队列,然后继续执行下一行代码,因此执行您的循环,而线程将等待500ms来执行您的警报。
如果希望for循环在500毫秒后运行,请执行以下操作
setTimeout(function(){
for (var i = 0; i < 5000; ++i) {
++k;
$('.inner').append('<p>Test</p>' + k.toString());
}
},500);https://stackoverflow.com/questions/16757538
复制相似问题