2015-07-28 126 views
-1

我想ping每個IP地址的數組/ JSON的可達性。這裏有一個簡單的場景:在for循環中使用Node.js child_process.exec() ping一個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被跳過了,我猜測這是因爲在返回.139的結果之前exec線程會覆蓋它自己。有沒有解決這個問題的方法?

回答

1

您正在嘗試使用同步循環來管理多個異步操作。 您可以使用exec_sync或重構您的代碼。

一個很好的解決方案將使用Promises和node.js bluebird是我的首選庫。

然後,你可以寫這樣的事情(也許imrpove吧!):

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