我想ping一个数组/ JSON中的每个IP地址以获得它们的可访问性。这是一个简单的场景:
var onlineCams = {};
for (var i = 0; i < ipList.cameras.length; i++) {
var currentIp = ipList.cameras[i].ip;
var currentIpStatus = "";
var shellCmd = 'ping -c 1 ' + currentIp + ' | grep icmp* | grep bytes | wc -l';
var child = exec(shellCmd, function (error, stdout, stderr) {
if (stdout.toString().trim() == '1')
currentIpStatus = "Online";
else
currentIpStatus = "Offline";
onlineCams[currentIp] = currentIpStatus;
});
}
示例输出:
// console.log(ipList.cameras);
[ { id: 0, ip: '192.168.79.139' },
{ id: 1, ip: '192.168.79.16' } ]
// console.log(onlineCams);
{ '192.168.79.16': 'Online' }
onlineCams
中只有一个IP地址应该有两个。出于某种原因,跳过了.139,我猜它是因为exec
线程在.139的结果被返回之前覆盖了自己。这有什么变通方法吗?
答案 0 :(得分:2)
您正在尝试使用同步循环来管理多个异步操作。 您可以使用exec_sync或重构代码。
一个不错的解决方案是使用Promises,而node.js bluebird是我首选的库。
然后你可以写这样的东西(也许是非常好的!):
var Promise = require('bluebird');
var exec = require('child_process').exec;
var ipList = {
cameras: [{
ip: 'yahoo.com'
}, {
ip:'google.com'
},{
ip: 'fake.fake'
}]
};
var onlineCams = {};
var promises = [];
function checkIp(ip) {
return new Promise(function (resolve, reject) {
var shellCmd = 'ping -c 1 ' + ip + ' | grep icmp* | grep bytes | wc -l';
exec(shellCmd, function (err, stdout, stderr) {
if (err) {
reject(err);
}
var result = {};
result[ip] = stdout.toString().trim() === '1' ? 'Online' : 'Offline';
resolve(result);
});
});
}
for (var i = 0; i < ipList.cameras.length; i++) {
promises.push(checkIp(ipList.cameras[i].ip));
}
Promise.all(promises).then(function (results) {
console.log(results);
});