代码可能看起来比它需要的更复杂我想将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)中,...
答案 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)
i
为0
,并在其余的调用中保持这种状态。
您可以创建一个闭包以在声明时捕获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);
}