2012-04-05 22 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