【问题标题】:Javascript: setTimeout, for loops, and callback functionsJavascript:setTimeout、for 循环和回调函数
【发布时间】:2013-12-11 10:01:18
【问题描述】:

我正在处理来自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 之间等待 i 毫秒)。

谁能帮我理解这个?

【问题讨论】:

标签: javascript for-loop callback settimeout


【解决方案1】:

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

  1. 闭包导致始终打印值1000 而不是100200 ...等。
  2. 您使用的超时时间太短,因此函数连续快速执行。

第一个问题很难用一个答案来解释,但我会尝试给你一些见解,因为将变量值打印到控制台的函数是在 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));
        ^^^^

【讨论】:

  • 我试过了,它只是立即注销了“1000”10次。
  • @Ber 我已将我的答案完全修改为新答案,请检查编辑。我第一次回答时很忙,把一切都搞砸了,对不起。
  • 感谢 Sniffer 的解释,我按照这些思路修改了代码,现在可以使用了!
  • @Ber 欢迎您,很高兴我能提供帮助。你需要深入阅读闭包,因为它们是一个讨厌的主题,但是一旦你很好地理解了它们,你会发现它们非常有用。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-28
    • 2018-01-11
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多