【问题标题】:JS: trying to use setTimeout with incremental valuesJS:尝试将 setTimeout 与增量值一起使用
【发布时间】:2014-07-05 23:32:11
【问题描述】:

我正在尝试在我的函数调用中使用增量 ID 设置循环延迟,以及逐渐增大的延迟时间。我设置的是这样的:

var delay = 0;
var delayMilliseconds = 250;
timeOutArray = [];

for(var i=0; i<100; i++){
    delay = i*delayMilliseconds;

    timeOutArray[i] = setTimeout(function(){
            loadRoute(modelsArray[i], (i+1));
        },delay);
}

我遇到的问题是,当任何 loadRoute() 函数被调用时,被引用的“i”已经增加到 99。

我正在寻找一种方法让它在我设置超时时识别“i”的数量,而不是在超时发生的那一刻。

我发现这篇关于使用“承诺”的文章,但有点令人困惑。 Javascript - Wait the true ending of a function that uses setTimeout

有人可以告诉我如何在这些调用中实现承诺,或者任何可以在不将 setTimeout 代码全部包装在 eval() 中的情况下实现的方法吗?

【问题讨论】:

    标签: javascript delay settimeout intervals


    【解决方案1】:

    这是您的代码的工作示例。问题在于对Scope & Closure的误解。

    var delay = 0;
    var delayMilliseconds = 250;
    timeOutArray = [];
    
    for (var i=1; i<100; i++) {
        (function(j){
            delay = j*delayMilliseconds;
            timeOutArray[j] = setTimeout(function(){
                console.log(j)
                //loadRoute(modelsArray[j], (j+1));
            },delay);
        })( i );
    }
    

    说明:

    (function(j){
     //this part of the code create new scope
    })( i );
    

    在每次迭代中使用above function为每个iteration创建了一个新范围,这给了我们的超时 > 函数回调为每次迭代关闭一个新范围的机会,其中有一个变量,其中包含正确的每次迭代值供我们访问。

    Source - For more info

    【讨论】:

    • 非常感谢。这在我的代码的现有上下文中解决了我的问题。另外,很高兴知道我需要学习 Scope & Closure。
    • 如果有帮助,请采纳答案,可能对其他用户有帮助。
    【解决方案2】:

    将其保存在闭包中以保留原始值。

    timeOutArray[i] = setTimeout( (function(i) { return function(){
        loadRoute(modelsArray[i], (i+1));
    }) (i),delay);
    

    基本上,您在每次循环迭代中创建并执行一个新的匿名函数,并将当前i 的副本传递给它。执行时,此函数返回另一个匿名函数,然后将其传递给setTimeout。但是,此函数保留了对其创建的作用域的引用,因此可以看到外部匿名函数保存的 i

    这有点棘手。你可以在 JavaScript 中搜索闭包。

    【讨论】:

    • 感谢您的帮助。尽管在这一行上,我实际上得到了该代码的语法错误:}) (i),delay); SyntaxError: missing;声明之前
    【解决方案3】:

    要么这样,要么在 for 循环之外定义超时函数并调用它:

    var delay = 0;
    var delayMilliseconds = 250;
    
    function doTimeoutStuff(i, delay) {
        setTimeout(function () {
            loadRoute(modelsArray[i], (i+1));
        }, delay);
    }
    
    for (var i=0; i<5; i++) {
        delay = i*delayMilliseconds;
        doTimeoutStuff(i, delay);
    }
    

    【讨论】:

      【解决方案4】:

      setTimeout() 允许您在执行时将变量传递给回调函数,而不是创建一个闭包,然后该函数将在回调函数内部并在回调期间持续存在。

      setTimeout(function[, delay, arg1, arg2, ...]);

      来源:MDN - setTimeout

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-08
        • 2016-03-25
        相关资源
        最近更新 更多