【问题标题】:setTimeout is not working correctly inside "for loop"setTimeout 在“for 循环”中无法正常工作
【发布时间】:2013-06-26 21:37:30
【问题描述】:

当然,代码只做你让它做的事情。

但我很困惑为什么在下面的代码中:

var a = {
    0: "Hi",
    1: "Bye"
}

for (var b in a) {
    setTimeout(function () {
        console.log(b);
    }, 1000);
}

而不是安慰“0”然后是“1”

我只得到两次“1”。

我不确定为什么会这样。我需要为我正在制作的脚本设置这样的设置,但我也遇到了同样的问题。

【问题讨论】:

    标签: javascript loops for-loop iteration settimeout


    【解决方案1】:

    这是因为你对闭包的使用是错误的。

    在这种情况下,您在setTimeout 回调中使用了闭包变量b,但是直到执行回调后才查找变量b 的值,然后更新到最后的值对象中的值。

    在这种情况下,解决方案之一是创建一个本地闭包,如下所示

    for (var b in a) {
        (function(c){
            setTimeout(function () {
                console.log(c);
            }, 1000);
        })(b)
    }
    

    演示:Fiddle

    【讨论】:

      【解决方案2】:

      你也可以这样做

      for (var b in a) {
          setTimeout(console.log.bind(console, b), 1000);
      }
      

      或者像这样

      for (var b in a) {
          setTimeout(function(c) {
              console.log(c)
          }.bind(null, b), 1000);
      }
      

      甚至像这样

      // compatibility varies
      for (var b in a) {
          setTimeout(function(c) {
              console.log(c)
          }, 1000, b);
      }
      

      【讨论】:

      • 更像setTimeout(console.log.bind(console, b)
      • @Musa, console.log.bind(null, b) 也适用于这种情况。 console.log 不需要自己的上下文来工作。
      • 所以你没有得到Illegal Invocation
      • @Musa,嗯,在node-0.10.12 中它与null 一起使用,但在浏览器中它看起来需要console。感谢您发现这种差异。我只做节点工作,所以我从来没有注意到:)
      猜你喜欢
      • 1970-01-01
      • 2017-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-27
      • 1970-01-01
      • 1970-01-01
      • 2013-03-31
      相关资源
      最近更新 更多