在超时循环内执行一系列函数

时间:2013-10-01 23:38:30

标签: javascript settimeout

我想执行一系列函数调用,每个调用都会在屏幕上发布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()

时间戳以毫秒为单位,因此没有发生延迟。

1 个答案:

答案 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:它只能导致痛苦和难以维护的代码。最好使用匿名函数;从我所看到的你的问题来看,没有理由你不能这样做。