【问题标题】:jQuery setTimeOut: in for-loopjQuery setTimeOut:在 for 循环中
【发布时间】:2015-04-08 14:28:29
【问题描述】:

我在使用 setTimeOut 函数时遇到了一点问题。虽然我看到了其他有关此功能的主题,但我仍然不明白。

我想生成 5 个“兽人”,但不是同时生成。所以我想给每个 fe 5 秒的延迟。我创造的最好的东西是一个无限循环,但我不知道为什么它在 4 之后没有停止。

for (var z = 0; z < 4; z++) {
    (function (z) {
        setTimeout(function () {
            $("#gameBoard").append("<img class='Orc' src='Img/Orc.gif' alt='Orc'/>");
            $( ".Orc" ).animate({ "left": "+=100%" }, 20000 );
            console.log("test");
        }, 4000);
    }(z))
}

这只会产生一个兽人。为什么会这样?

它不必与传递的变量一起使用。

有什么想法吗?

【问题讨论】:

  • 您发布的代码应该停止,但它会同时创建所有四个兽人(尽管在循环完成后四秒)。此外,由于您没有异步使用z,因此不需要对其进行闭包。

标签: javascript jquery performance for-loop settimeout


【解决方案1】:

如果您希望每个兽人的延迟时间不同,您必须通过setTimeout 每个兽人不同的延迟时间:

for (var z = 0; z < 4; z++) {
    (function (z) {
        setTimeout(function () {
            $("#gameBoard").append("<img class='Orc' src='Img/Orc.gif' alt='Orc'/>");
            $( ".Orc" ).animate({ "left": "+=100%" }, 20000 );
            console.log("test");
        }, 4000 * z);
    }(z))
}

请注意,我将延迟乘以 z

【讨论】:

    【解决方案2】:

    你可以试试这样的:

    var orcsSent = 0;
    
    function sendOrc() {
        $("#gameBoard").append("<img class='Orc' src='Img/Orc.gif' alt='Orc'/>");
        $( ".Orc" ).animate({ "left": "+=100%" }, 20000 );
        console.log("test");
    
        if(orcsSent < 5) {
            orcsSent++;
            setTimeout(function () {
                 sendOrc();
            }, 4000);
        }
    }
    
    sendOrc();
    

    【讨论】:

    • 注意:不需要 sendOrc() 周围的匿名函数 - 只需调用 setTimeout(sendOrc, 4000)
    【解决方案3】:

    为了更简洁地实现@lpg 的答案:

    function sendOrcs(n) {
        (function loop() {
            if (--n < 0) return;
            $("#gameBoard").append("<img class='Orc' src='Img/Orc.gif' alt='Orc'/>");
            $( ".Orc" ).animate({ "left": "+=100%" }, 20000 );
            setTimeout(loop, 4000);
        })();
    }
    

    注意:这将立即生成第一个兽人,而不是 4 秒后。

    【讨论】:

    • 谢谢!如果我在游戏中进一步进步,这可能会变得很方便。
    【解决方案4】:

    使用 if 然后再次调用该函数。

    例如

    var step = 0
    function SpawnOrcs(){
        [code for orc spawn]
        if (step <4)
        {
            step++
            setTimeout(SpawnOrcs,[time to wait in ms])
        }
    }
    

    【讨论】:

    • 从不ever将字符串参数传递给setTimeout()
    • 因为这就是我们在 90 年代编写 JS 的方式。它可以工作,但它很讨厌,容易出现安全问题,并且会阻止诸如范围界定之类的事情发挥作用。
    • 好的,我改了。它还会导致哪些安全问题?
    • eval 拥有的所有相同的,AFAIK。
    • 另外,约定说不要对你的函数进行 TitleCase,除非它们应该被称为构造函数。
    【解决方案5】:

    你需要的是兽人的名字!

    试试这个:

    function spawnOrcs(numberOfOrcs) {
    
        var interval = 2000;
        var orcNames = ["Graklak Glasha", "Ougigoth Batul", "Zoughat Ushug", "Graman Lash", "Grushnag Sharn", "Urgan Bumph", "Raghat Durgat", "Xujarek Uloth", "Wumkbanok Bor", "Gnarlug Umog"];
    
        for (var i = 0; i < numberOfOrcs; i++) {
            var name = orcNames[i % orcNames.length];
            (function(i, name) {
                setTimeout(function() {
                    console.log("Spawned Orc:", name);
                }, interval * (i + 1))
            })(i, name);
        }
    
    }
    
    spawnOrcs(5);
    

    当您考虑将此标记为有史以来的最佳答案时,我会在这里耐心等待! :D

    【讨论】:

    • 大声笑 ;) 我将来可能会实现它!感谢您的想法!
    • 你的兽人只有名字,没有尸体。
    • 如果名字做对了,它引起的恐惧意味着不需要身体!
    猜你喜欢
    • 2014-05-18
    • 2019-08-21
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    • 2016-08-30
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    相关资源
    最近更新 更多