我正在将一个变量传递给一个函数,并且没有看到我的错误

时间:2012-07-05 21:08:10

标签: javascript function

代码可能看起来比它需要的更复杂我想将i传递给balm函数但它返回undefined因为我做错了。
只是额外的信息:这是我正在写的游戏的服务器。在控制台中运行节点。

for (i=30;i>=0;i--){
   setTimeout(function balm(i){
      this_sql ="UPDATE game_moblist SET hp = least(max_hp, hp +"+Math.round(i/2)+") WHERE id ="+mobid
      connection.query(this_sql, function(err, rows, fields) {if (err) err=null});
      console.log(this_sql)
      this_sql ="SELECT hp, max_hp FROM  game_moblist WHERE id ="+mobid;   //emite catch all update pointint to hp..
      connection.query(this_sql, function(err, rows, fields) {if (err) throw err;
      socket.emit ('updatemisc',handler,rows);//eval handler using args
      if (rows[0].hp==rows[0].max_hp){
         i=0;
         return i;
      }
      });
   },(31-i)*333);
}

这是一个简化版本,只显示了概念

for (i=3;i>=0;i--){
   setTimeout(function foo(i){
      console.log(foo)
   },1000*i);

我希望得到以下输出 1000毫秒后“1” 2000毫秒后的“2” 3000毫秒后的“3” 编辑:当我在setTimeout()之外定义函数然后像这样调用它时,它工作 的setTimeout(唇膏(i)中,...

3 个答案:

答案 0 :(得分:2)

你不能使用在回调函数之外声明的循环变量i,并且在回调实际执行后期望它具有正确的值 - 它将为其分配最后一个值。

下面的代码显示了最简单(但不是最短)的解决方案:

function showNumber(n) {
    return function() {
        console.log(n);
    }
}

for (i = 3; i >= 0; i--) {
     setTimeout(showNumber(i), 1000 * i);
}

换句话说,你调用一个函数(它的参数“绑定”到你的循环变量)然后返回另一个函数,它是setTimeout()实际调用的函数。 / p>

还有其他方法可以实现这一点,通常使用立即调用的函数表达式,如@ Xander的答案所示,但上面的代码很好地演示了解决方案。

答案 1 :(得分:1)

当第一个回调执行时,<{i0,并在其余的调用中保持这种状态。

您可以创建一个闭包以在声明时捕获i的值:

for (i = 3; i >= 0; i--){
    function(x) {
        setTimeout(function foo(i){
            console.log(i)
        },1000 * x);
    })(i);
}

答案 2 :(得分:0)

变量不能在声明中传递给函数。

    for (i=3; i>=0; i--) {
        fooLoop(i);
    }

    function fooLoop(iterator) {
        setTimeout(function () {
            console.log("value of i is" + iterator);
        }, 1000*iterator);
    }