JS - 如何正确使用setTimeout()

时间:2012-07-05 22:05:35

标签: javascript node.js

所以我有这个函数在setTimeout上执行,而console.log为我命名的时间变量返回正确的值但是当我运行代码时函数运行没有延迟。代码是我正在制作的游戏的服务器端。该代码应该在使用项目后逐渐恢复玩家的健康状况。我的问题是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;
        }
    });
}
for (i=30;i>=0;i--){
   time=(31-i)*1000;
   console.log(time);
   setTimeout(balm(i),time);
}

2 个答案:

答案 0 :(得分:5)

这是setTimeout

的正确用法
setTimeout(balm, time, i);

你必须传递一个函数,然后延迟,然后args到前面提到的函数

答案 1 :(得分:5)

问题在于:

setTimeout(balm(i),time);

它的作用是致电 balm并将其返回值提供给setTimeout,这不是您想要的。您希望传递setTimeout一个函数,该函数在调用时将使用给定的balm值调用i。你这样做:

setTimeout(makeHandler(i),time);
function makeHandler(index) {
    return function() {
        balm(index);
    };
}

这样,balm函数稍后会被调用,并且会在超时计划时使用i值进行调用。如果没有makeHandler内容,所有balm个实例都会看到i,就像他们运行时那样(例如,他们都看到-1) 。这是因为在JavaScript中,闭包具有对上下文中变量的持久访问;创建闭包时,不是它们的副本。所以他们都看到i的当前值。 (更多:Closures are not complicated

(请注意,在NodeJS上 - 您正在使用的环境 - 以及Firefox上,您可以使用{strong>非标准扩展名setTimeout,允许您提供参数传递对于该功能;请参阅pksunkara's answer。但对于任何希望在网络上进行客户端访问的人[而不是使用Node的服务器端],请注意,不是标准。)< / p>

为了说明这一点,这是一个例子(这个在浏览器中运行,但对于像NodeJS这样的服务器端的东西也是如此):

(function() {

  // Wrong
  setTimeout(function() {
    var i;

    for (i = 0; i < 5; ++i) {
      setTimeout(function() {
        show("wrong", i);
      }, i * 50);
    }
  }, 0);

  // Right
  setTimeout(function() {
    var i;

    for (i = 0; i < 5; ++i) {
      setTimeout(makeHandler(i), i * 50);
    }

    function makeHandler(index) {
      return function() {
        show("right", index);
      };
    }
  }, 500);

  function show(marker, val) {
    display("show (" + marker + "): " + val);
  }

  function display(msg) {
    var p = document.createElement('p');
    p.innerHTML = String(msg);
    document.body.appendChild(p);
  }
})();

Live copy | source

这是输出:

show (wrong): 5
show (wrong): 5
show (wrong): 5
show (wrong): 5
show (wrong): 5
show (right): 0
show (right): 1
show (right): 2
show (right): 3
show (right): 4