Node.js – 请帮我recursion
我有以下Node.js代码:
var exec=require('child_process').exec; var base_ctrl_port=8118; var base_data_port=9050; var nConns=10; watchdogCycle(); setInterval(watchdogCycle, 60000); //check health every 60 seconds... function watchdogCycle(){ console.log("\n"); for(var i=0;i<nConns;i++){ var data_port=base_data_port+i; data_port=data_port+""; var curl=exec('curl -b -s --socks5 localhost:'+data_port+' http://ifconfig.me',{timeout:10000}, function(err,stdout,stderr){ console.log(stdout); if(err!=null){ getNewIP(i); //PROBLEM: i is always 10!!! } }); } } function getNewIP(offset){ console.log("Getting new IP address for tor data port: "+(base_data_port+offset+0)+"..."); var ctrl_port=base_ctrl_port+offset; var nc=exec('(echo AUTHENTICATE \'\"xxxxxx\"\'; echo SIGNAL NEWNYM; echo quit) | nc localhost '+ctrl_port, function(err,stdout,stderr){ console.log(stdout); }); }
问题是, getNewIP(i)
中的参数i
始终为10!
我已经读了一些关于recursion,但我不知道如何修改这个代码,所以i
是0..9,而不是总是10。
提前谢谢了,
这是closures的问题…
尝试这个:
for(var i=0;i<nConns;i++){ var data_port=base_data_port+i; data_port=data_port+""; (function (i){ // <----- var curl=exec('curl -b -s --socks5 localhost:'+data_port+' http://ifconfig.me',{timeout:10000}, function(err,stdout,stderr){ console.log(stdout); if(err!=null){ getNewIP(i); //PROBLEM: i is always 10!!! } }); })(i); // <----- }
简单地说你的问题与此成正比:
for(i = 0; i < 10; i++){ setTimeout(function(){ alert(i);}, 1000); }
为了解决这个问题,你可以把你的代码包装在一个新的函数中:
for(i = 0; i < 10; i++){ (function(otherI){ setTimeout(function(){ alert(otherI); }, 1000); })(i) }
这是人们在使用闭包时经常遇到的已知问题!
你可以参考这个线程的更多信息,因为问题是基本相同的: 传递函数setTimeout在一个循环:总是最后一个值?
这也是一个很好的参考: Javascript臭名昭着的循环问题?
为了更可读的语法,你也可以做一些事情:
for(i = 0; i < 10; i++){ with({i: i}){ setTimeout(function(){ alert(i);}, 1000); } }