Javascript:setTimeout,for循环和回调函数

时间:2013-11-26 10:13:34

标签: javascript for-loop callback settimeout

我正在处理来自here

的代码拼图

这是我到目前为止所拥有的:

for (var i = 0; i < 1000; i += 100) {
    waitFor(i, function then() {
    console.log(i)
    })
}

// this will run a callback function after waiting milliseconds
function waitFor(milliseconds, callback) {
    setTimeout(callback.apply(), milliseconds)
}

这会记录0到900,但它会立即执行所有操作,然后在结束时等待900毫秒(而不是在每个console.log之间等待1毫秒)。

任何人都可以帮我理解这个吗?

2 个答案:

答案 0 :(得分:0)

您的代码中存在两个不同的问题:

  1. 闭包导致值1000始终打印而不是100200等等。
  2. 您使用的超时时间太短,因此功能会连续快速执行。
  3. 第一个问题很难在单个答案中解释,但我会尝试给你一些见解,因为在for循环中定义了将变量值打印到控制台的函数,该函数将始终保持循环结束时存在的i值,在您的情况下为1000

    要解决这个问题,你需要类似@ thg435在评论中提到的内容,如下所示:

    // this will run a callback function after waiting milliseconds
    function waitFor(milliseconds, callback) {
        setTimeout(callback, milliseconds);
    }
    
    function createFunction(i) {
        return function() { console.log(i); };
    }
    
    for (var i = 0; i < 1000; i += 100) {
        waitFor(i, createFunction(i));
    }
    

    第二个问题是超时的值实际上是i所采用的值,因为它是循环的100200 ...等等都非常小值小于一秒,所以当for循环结束时,这些函数都准备好执行,这样它们就会一个接一个地立即执行。

    要解决此问题,您需要通过将i乘以10来使用更大的时间间隔,例如,如下所示:

    waitFor(i*10, createFunction(i));
            ^^^^
    

答案 1 :(得分:0)

循环结束时将发生第一次定时器调用。在这种情况下,由于JS使用引用而不是值,因此i = 1000。要解决这种情况,你必须使用闭包。