我想执行一系列函数调用,每个调用都会在屏幕上发布jGrowl消息。当我毫不拖延地执行此操作时,屏幕上不会显示任何内容。当我尝试在延迟循环中设置延迟时,所有调用都会立即执行。
以下是代码:
var tests = [];
tests.push("$.notification('this is a test');");
tests.push("$.notification('this is a test', 7);");
tests.push("$.notification({ message: 'this is a test', code: 'warning', sticky: false });");
tests.push("$.diagnostic({ message: 'click OK to continue', alert: true });");
tests.push("$.notification.erase();");
//为什么这不起作用?
//>
function wait(ms){
var done = false;
while(!done){
setTimeout(function(){
done = true;
}, 女士)
}
}
这是控制台:
16.30.6.265: : Executing test[0]: $.notification('this is a test');
16.30.6.266: : Executing test[1]: $.notification('this is a test', 7);
16.30.6.266: : Executing test[2]: $.notification({ message: 'this is a test', code: 'warning', sticky: false });
16.30.6.266: : Executing test[3]: $.diagnostic({ message: 'click OK to continue', alert: true });
16.30.6.266: : Executing test[4]: $.notification.erase()
时间戳以毫秒为单位,因此没有发生延迟。
答案 0 :(得分:1)
问题是setTimeout
没有“堆叠”。也就是说,当您调用setTimeout
后跟另一个setTimeout
时,JavaScript不执行第一个,然后执行第二个。它说“哦,嘿,从现在开始这两次超时”。如果那个时间是相同的,那么它们将同时执行(或者彼此在几微秒内执行;也不应该依赖于在另一个之前执行的一个)。
您的问题有两种解决方案。您可以每次增加超时,以便事件以交错的方式发生,或者您可以链接超时,以便第一个触发第二个,第二个触发第三个,依此类推。
我认为第一种方法(递增超时)可能会产生一种更简单,更清晰的解决方案,所以我将在此处提出:
delay = 500; // half a second between messages
for (var i = 0; i < tests.length; i++) {
t = tests[i];
$.diagnostic('Executing test[' + i + ']: ' + t);
(function (index,t) {
setTimeout(function() {
eval(t);
}, index*delay);
})(i,t);
}
顺便说一句,强烈建议不要使用eval
:它只能导致痛苦和难以维护的代码。最好使用匿名函数;从我所看到的你的问题来看,没有理由你不能这样做。