提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
有次循环调用net.connect,判断服务器网络状态,在回调方法中修改obj状态,发现obj变量获取错乱问题。
1.错误代码
代码如下(示例):
function monitDownUrl(){
for(index in heartDownUrlList) {
var downObj = heartDownUrlList[index];
var downUrl = downObj.url;
try{
let urlObj = url.parse(downUrl);
var defPort = urlObj.protocol === "https:" ? 443 : 80
var port = urlObj.port ? urlObj.port : defPort
var client = net.connect({port: port, host: host}, function() {
downObj.failNum = 0;
downObj.status = true;
logger.log('connected server',host);
client.end()
});
client.setTimeout(4000);
client.on('end', function() {
//logger.log('end', downObj.url);
});
client.on('timeout', () => {
logger.log('connect timeout',downObj.url);
if (downObj.status) {
downObj.failNum++;
if (downObj.failNum > 3) {
downObj.status = false;
}
}
client.end();
});
client.on('close', function () {
//logger.log("connect close",downObj.url)
});
client.on('error', function (err) {
logger.log("connect error",downObj.url,err)
if (downObj.status) {
downObj.failNum++;
if (downObj.failNum > 3) {
downObj.status = false;
}
}
});
}catch(err){
logger.log('monitDownUrl执行错误:',downUrl, err)
}
}
setTimeout(function(){monitDownUrl()}, 5 * 1000)
}
2.正确代码
function monitDownUrl(){
for(index in heartDownUrlList) {
var downObj = heartDownUrlList[index];
var downUrl = downObj.url;
try{
let urlObj = url.parse(downUrl);
//logger.log('urlObjurlObj',JSON.stringify(urlObj));
var defPort = urlObj.protocol === "https:" ? 443 : 80
var port = urlObj.port ? urlObj.port : defPort
tcpConn(urlObj.hostname, port, downObj)
}catch(err){
logger.log('monitDownUrl执行错误:',downUrl, err)
}
}
setTimeout(function(){monitDownUrl()}, 5 * 1000)
}
function tcpConn(host, port, downObj) {
var client = net.connect({port: port, host: host}, function() {
downObj.failNum = 0;
downObj.status = true;
logger.log('connected server',host);
client.end()
});
.......
}
总结
问题原因是js单线程处理和net.connect为异步,在创建句柄时,循环已经走完,在处理异步代码时局部变量被覆盖,导致所有的连接被最后一个覆盖.处理办法将要修改的变量放入新创建的方法中,在新方法中使用net.connect.即可。