0

代码可能看起来比它需要的更复杂我想将 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(balm(i) ……

4

3 回答 3

2

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

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

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

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

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

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

于 2012-07-05T21:11:06.723 回答
1

i0第一个回调执行并在其余调用中保持这种方式的时间。

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

for (i = 3; i >= 0; i--){
    function(x) {
        setTimeout(function foo(i){
            console.log(i)
        },1000 * x);
    })(i);
}
于 2012-07-05T21:12:23.907 回答
0

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

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

    function fooLoop(iterator) {
        setTimeout(function () {
            console.log("value of i is" + iterator);
        }, 1000*iterator);
    }
于 2012-07-05T21:14:14.200 回答