0

したがって、setTimeout で実行されるこの関数があり、console.log は time という名前の変数の正しい値を返しますが、コードを実行すると関数は遅延なく実行されます。コードは、私が作成しているゲームのサーバー側です。このコードは、アイテムを使用した後、プレイヤーの健康を徐々に回復することになっています。私の問題は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);
}
4

2 に答える 2

6

問題はここにあります:

setTimeout(balm(i),time);

それが行うことは、呼び出し balmてその戻り値を to にフィードすることですがsetTimeout、これはあなたが望むものではありません。呼び出されたときに特定の値でsetTimeout呼び出す関数を渡したいとします。次のようにします。balmi

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

そうすれば、balm関数は後で呼び出されi、タイムアウトがスケジュールされたときの値で呼び出されます。makeHandlerモノがなければ、すべてのbalmインスタンスは、実行iしたときと同じように表示されます(たとえば、すべてのインスタンスは を表示します)。これは、JavaScript では、クロージャがコンテキスト内の変数に永続的にアクセスできるためです。クロージャーが作成されたときのコピーではありません。したがって、それらのすべてが の現在の値を確認します。(詳細:閉鎖は複雑ではありません)-1i

(NodeJS (使用している環境) と Firefox でも、非標準の拡張機能をsetTimeout使用して、関数に渡す引数を指定できることに注意してください。pksunkara の回答を参照してください。 Web 上のクライアント側 [Node を使用したサーバー側ではなく]、注意してください。これは標準ではありません。)

これを説明するために、以下に例を示します (これはブラウザーで実行されますが、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);
  }
})();

ライブコピー| ソース

出力は次のとおりです。

ショー (間違った): 5
ショー (間違った): 5
ショー (間違った): 5
ショー (間違った): 5
ショー (間違った): 5
表示 (右): 0
ショー (右): 1
ショー (右): 2
ショー (右): 3
ショー (右): 4
于 2012-07-05T22:10:11.027 に答える
5

これは setTimeout の正しい使い方です

setTimeout(balm, time, i);

関数を渡し、次に遅延し、次に引数を前述の関数に渡す必要があります

于 2012-07-05T22:10:02.150 に答える