【问题标题】:Can't manage to sleep inside a loop无法在循环中睡觉
【发布时间】:2012-03-26 21:42:11
【问题描述】:

我想在每次循环时暂停1 second,在其他情况下进行类似的暂停通常很容易,但是在使用循环时,似乎变得更难了:

for (var i=0 ; i < 10 ; i++) {
    document.write (i + "<br>");
    // I want to wait 1 second here
}

这是我数千次失败尝试的一个例子:

function writeMsg (index) {
    document.write (index + "<br>");
}

for (var i=0 ; i < 10 ; i++) {
    setTimeout (writeMsg(i), 1000);
}

关于如何让它发挥作用的任何想法?

【问题讨论】:

标签: javascript loops delay sleep


【解决方案1】:

这个函数的工作方式更像是一个普通的 for 循环,而实际上不是

您需要考虑到 for 在分号之间有 3 个参数。

  1. 开始之前(即var i=0你定义一个变量)
  2. 再次运行代码之前的条件(即i &lt; 10,而我未满 10 岁)
  3. 每次完成代码时的动作(i++ i 加一)

代码

(function() {
    // Define a variable
    var i = 0,
        action = function() {
            // Condition to run again
            if (i < 10) {
                document.write(i + "<br>");

                // Add one to i
                i++;
                setTimeout(action, 1000);
            }
        };

    setTimeout(action, 1000);
})();

这里是这段代码的 jsfiddle,展示了它的工作原理: http://jsfiddle.net/sg3s/n9BNQ/

【讨论】:

  • 我的代码可以通过包装来简化,如果围绕新的 setTimeout 而不是整个函数,我猜。
【解决方案2】:

您将函数调用的返回值传递给setTimeout 而不是函数。试试下面的代码:

for (var i = 0; i < 10; i++) {
    (function(i) {
        setTimeout(function() {
            writeMsg(i);
        }, 1000*i);
    })(i);
}

如果您想知道为什么调用被包装在匿名函数中:如果没有该函数,每个 setTimeout 回调都会收到相同的i,因此当回调触发时,它总是10。匿名函数在内部创建了一个新的i,它没有连接到循环变量。

【讨论】:

  • 它们同时打印(Chrome)
  • 是的,我忘记了1000*i 而不仅仅是1000。您可能复制了初始版本。
  • 它每次都打印10。但我可以通过一些修改使其工作
  • 立即尝试。混合了两个功能
  • 这只会启动 x 次超时,而这适用于少量超时,如果您尝试启动太多次将是地狱。这也忽略了通过将 i 设置为高于 10 来中途中断 for 循环的可能性。在我看来,这是一种非常可怕的方法。
【解决方案3】:

经典的函数在循环问题。一个原型解决方案:

function createCallback(i) {
    return function () {
        writeMsg(i);
    };
}

function writeMsg (index) {
    document.write (index + "<br>");
}

for (var i=0 ; i < 10 ; i++) {
    setTimeout (createCallback(i), 1000*i);
}

【讨论】:

  • 天啊,把括号搞砸了。这就是为什么我无论如何都喜欢单独的回调生成器 - 更容易编写,更容易阅读。
  • 不好的做法,你会启动多个超时并打破正常的功能,因为你不能改变 i 以影响代码的其他潜在循环。
  • @sg3s 对不起?你的评论不清楚。我不能说我听说过安排 O(10) 超时会导致问题。
  • 这是不好的做法。 OP 不只是想向文档写一条消息,而且显然一次又一次地执行几个或相同的操作。这样做不会让您在开始所有超时后进行干预,作为开始,而他可能会在循环 #5 处决定出于 w/e 原因已经足够了,然后将 i 设置为 10.. .他要求一个for循环,每个循环都被延迟。不是用不同的变量触发函数 x y 次的方法,也无法停止他们将要执行的操作。
【解决方案4】:

10 次超时都是基于调用 setTimeout() 的时间。所以,它们都是同时触发的。

for (var i=0; i < 10; i++) {
    (function(idx){
        setTimeout(function(){
            document.write(idx+"<br/>");
        },1000*idx);
    })(i);
};

【讨论】:

  • 不好的做法,你会启动多个超时并打破正常的功能,因为你不能改变 i 以影响代码的其他潜在循环。
【解决方案5】:

试试这个,它肯定会帮助所有想如何让它在 For 循环中工作的等待属性的人...... 在此 URL http://www.shopjustice.com/the-collections/C-10329 中尝试此代码。

var var2;
var tmp;
var evt;
var i=0;
var res = document.getElementsByClassName('mar-plp-filter-content nav nav--stacked')[0].children.length;
tmp = document.getElementsByClassName('mar-plp-filter-content nav nav--stacked')[0].children;
function myfunc()
{
if(i<res)
{
var2 = tmp[i].getElementsByTagName("span")[0].getElementsByClassName("inverted")[0];
// alert(var2.innerHTML);
var evObj = document.createEvent('MouseEvents');
evObj.initEvent( 'mouseover', true, false );
var2.dispatchEvent(evObj);
var2.style.backgroundColor="GREEN";
i++;
setTimeout(myfunc,3000);
}
};
setTimeout(myfunc,3000);

【讨论】:

    猜你喜欢
    • 2021-05-17
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多