0

だから私がやろうとしているのは、javascript オブジェクト ( sensors) の配列をループし、それぞれにcmdparser属性を付け、それぞれcmdをシステム シェルで実行し、その出力を適切なparser関数で解析し、結果の文字列をサーバーのresオブジェクトに追加することです。

最初の問題は、現在のオブジェクトにメソッドがないというエラーが表示されることparserです。私はいくつかの異なることを試しましたが、オブジェクトのその属性を認識できません。

2 つ目の問題は、ループ内で解析関数をあきらめてハードコーディングしたとき (これにより、別のパーサーを必要とするコマンドを追加する機能が失われます)、各コマンドの出力がコールバック関数で読み取られるため、サーバーが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');
4

1 に答える 1

2

最初の問題は、各コールバック関数が同じs変数を参照した結果です。for(s in sensors)ループをに変更することで、これを簡単に解決できますsensors.forEach(function(s){...})。それはsを閉じ(google javascriptクロージャ)、時が来たときに各コールバックに適切なものにします。他の問題があるかもしれません-この問題を見た後、私はそれほど一生懸命に見えませんでした。

あなたの2番目の問題はまさにあなたが言ったことです。はres.end()コールバックの前に呼び出されます-それらは非同期であるため、実行の現在の「スレッド」が終了した後に呼び出されます。これは、単純なカウンターで解決できます。すべての呼び出しの前にインクリメントexecし、各コールバックでデクリメントして、カウンターが初期値に達しているかどうかを確認します。初期値に達している場合は、を実行しres.end()ます。

于 2012-04-05T01:36:13.717 に答える