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); } }