2012-07-05 41 views
0

代碼可能看起來比它需要更復雜我想將我傳遞到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); 

我希望2000年以後毫秒 「3」 3000毫秒後經過1000毫秒 「2」 以下輸出 「1」 的概念, 編輯:它的工作時,我定義setTimeout()之外的功能,然後叫它像這樣 setTimeout(香脂(我),...

回答

2

你不能使用循環變量i在回調函數之外聲明,並且期望它在實際執行回調後具有正確的值 - 它將具有爲其分配的最後一個值。

下面的代碼演示了最簡單的(但不是最短的)解決方案:

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

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

換句話說,你調用一個函數(即有它的參數「綁定」到你的循環變量),然後回報另一個函數是setTimeout()實際調用的函數。

還有其他的方法可以做到這一點,通常有一個即時調用函數表達式如@ Xander的答案中所示,但上面的代碼很好地演示瞭解決方案。

+0

這就是我剛纔發現感謝您的快速反應。 – Shawn 2012-07-05 21:12:57

1

i0當第一個回調執行並保持這種方式通過其餘的呼叫。

您可以創建一個封閉在聲明的時刻捕捉到的i值:

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

實際上'我'是0 - 他的循環向後運行;-) – Alnitak 2012-07-05 21:16:25

0

變量不能被傳遞到在其聲明中的功能。

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

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