返回node.js中多个shell命令的结果

时间:2012-04-05 01:14:32

标签: javascript node.js asynchronous

所以我要做的是循环遍历javascript对象数组sensors),每个对象都有cmdparser属性,运行每个cmd in系统shell使用适当的parser函数解析其输出,并将结果字符串附加到服务器的res对象。

第一个问题是我收到错误声明当前对象没有方法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');

1 个答案:

答案 0 :(得分:2)

您的第一个问题是每个回调函数引用相同s变量的结果。您可以通过将for(s in sensors)循环更改为sensors.forEach(function(s){...})来轻松解决此问题。这将关闭(谷歌javascript关闭)s并在时机成熟时使其成为每个回调的正确选项。可能还有其他问题 - 一旦我看到这个问题,我看起来并不那么难。

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