2012-04-05 48 views
0

那么我现在要做的是遍历JavaScript对象(sensors),每个cmdparser属性,运行系统中的每个外壳的cmd一个数组,解析它的输出和相应的parser函数,并将结果字符串追加到服务器的res对象中。返回多个shell命令在node.js的结果

第一个问题是我得到一个错误,声称当前对象没有方法parser。我尝试了一些不同的东西,但仍然无法识别该对象的属性。

第二个问题是,当我放弃并硬编码循环内的解析函数(这会破坏我添加需要不同解析器的命令的能力)时,是因为每个命令的输出都在回调函数中读取,服务器在回调返回之前运行res.end(),导致对浏览器的空响应。

我对节点和JavaScript相当陌生,所以我确定我犯了一些初学者的错误,我似乎无法在我的脑海中将它们整理出来。任何帮助,将不胜感激。

// requires 
var http = require('http'); 
var exec = require('child_process').exec; 

// parsers 
var parseTemp = function(str) { 
    return ((parseInt(str, 16)/50 - 273.15).toFixed(2)); 
}; 

// sensors 
var sensors = [ 
    { 
     label: "Object temp", 
     cmd: "i2cget -y 3 0x5a 0x07 w", 
     parser: parseTemp, 
     units: " degrees C" 
    }, 
    { 
     label: "Ambient temp", 
     cmd: "i2cget -y 3 0x5a 0x06 w", 
     parser: parseTemp, 
     units: " degrees C" 
    } 
]; 

// server 
http.createServer(function (req, res) { 
    res.writeHead(200, {'Content-Type': 'text/plain'}); 
    for (var s in sensors) { 
     exec(s.cmd, function (error, stdout, stderr) { 
      res.write(s.label + ': ' + s.parser(stdout) + s.units + '\n'); 
     }); 
    } 
    res.end(); 
}).listen(1337, ''); 

console.log('Server running on port 1337'); 

回答

2

你的第一个问题是每个回调函数引用相同s变量的结果。您可以通过将for(s in sensors)循环更改为sensors.forEach(function(s){...})来轻松解决此问题。这将关闭(谷歌JavaScript关闭)的S,并使其成为每个回调的时候到了正确的。可能还有其他一些问题 - 一旦我看到这个问题,我并没有看到这一切。

你的第二个问题正是你所说的。 res.end()在回调之前被调用 - 因为它们是异步的,所以最好在当前执行的“线程”完成后调用。您可以用一个简单的计数器来解决这个问题:在每调用一次exec之前递增,并在每次回调中递减并检查计数器是否已达到其初始值 - 如果是,则运行res.end()

+1

完美的解决方案,非常感谢。 – Luke 2012-04-05 02:01:25