在node.js中检索JSON数据时出错

我试图做一个Android应用程序,显示我的AWS ec2实例上的顶部命令数据。 以下是我写的node.js文件。 它使用topparser npm模块发送最高命令结果。 并且使用checkCpuUsage函数,如果cpu使用率大于1%,它会发送一个通知。

var express = require('express'); var app = express(); var fs = require('fs'); var spawn = require('child_process').spawn; var topparser=require("topparser"); var FCM = require('fcm-node'); var server = app.listen(8080); var regTokens = []; var bodyParser = require('body-parser'); app.use(bodyParser.json()); let data_builder = ""; const DEFAUT_TOP_DURATION = 2000; function getTopData(callback, duration) { duration = duration || DEFAUT_TOP_DURATION; var top = spawn('top'); top.stdout.on('data', function(data) { data_builder+=data.toString(); }); setTimeout(function() { top.kill(); callback(topparser.parse(data_builder,10)) },duration); } function sendServerData(req, res) { getTopData((data)=>{ res.status("200").send(data); }) } function checkCpuUsage() { getTopData((data)=>{ var idl = data.cpu.idle; if(idl<99) { sendNotification(idl); } }, 2000) } function saveRegToken(req, res) { console.log("saveRegToken req body", req.body) regTokens.push(req.body.token); res.send(200); } let server_key =JSON.parse(fs.readFileSync(('./config.json'))); ; function sendNotification(idle){ var idl = idle; var fcm = new FCM(server_key); for(i=0; i<regTokens.length; i++) { var message = { to: 'regTokens[i]', notification: { title: 'CPU Usage!', body: 'CPU Usage: ' + idl, }, }; fcm.send(message, function(err, response){ if (err) { console.log("Something has gone wrong!"); } else { console.log("Successfully sent with response: ", response); } }); } } setInterval(()=>checkCpuUsage(),10000); app.get('/sys', sendServerData); app.post('/save_token', saveRegToken) console.log("server listening on 8080"); 

我在checkCpuUsage()函数中得到以下错误:

 var idl = data.cpu.idle; ^ TypeError: Cannot read property 'cpu' of undefined at getTopData (/home/ubuntu/server_monitor/server1.1.1.js:38:17) at Timeout._onTimeout (/home/ubuntu/server_monitor/server1.1.1.js:26:3) at ontimeout (timers.js:469:11) at tryOnTimeout (timers.js:304:5) at Timer.listOnTimeout (timers.js:264:5) 

以下是topparser模块的示例JSON结果:

  { process:[ { pid:'1990', user:'alex', pr:'20', ni:'0', virt:'1560516', res:'90656', shr:'21864', s:'S', cpu:'6.1', mem:'12.5', time:'13:46.58', command:'cinnamon' }, { pid:'5381', user:'alex', pr:'20', ni:'0', virt:'929508', res:'119792', shr:'8132', s:'S', cpu:'6.1', mem:'16.5', time:'11:14.11', command:'firefox' }, { pid:'0245', user:'alex', pr:'20', ni:'0', virt:'24948', res:'1508', shr:'1056', s:'R', cpu:'6.1', mem:'0.2', time:'0:00.02', command:'top' }, { pid:'1', user:'root', pr:'20', ni:'0', virt:'37352', res:'5688', shr:'488', s:'S', cpu:'0.0', mem:'0.8', time:'0:04.93', command:'init' }, { pid:'2', user:'root', pr:'20', ni:'0', virt:'0', res:'0', shr:'0', s:'S', cpu:'0.0', mem:'0.0', time:'0:00.07', command:'kthreadd' }, { pid:'3', user:'root', pr:'20', ni:'0', virt:'0', res:'0', shr:'0', s:'S', cpu:'0.0', mem:'0.0', time:'0:54.23', command:'ksoftirqd/0' }, { pid:'4', user:'root', pr:'20', ni:'0', virt:'0', res:'0', shr:'0', s:'S', cpu:'0.0', mem:'0.0', time:'0:00.00', command:'kworker/0:0' } ], task:{ total:194, running:1, sleeping:193, stopped:0, zombie:0 }, cpu:{ user:0.9, system:3.1, ni:0.1, 'idle':95, wa:0.3, hi:0.6, si:0, st:0 }, ram:{ total:727308, used:664028, free:63280, buffers:7600 }, swap:{ total:753660, used:309516, free:444144, cachedMem:187424 } } 

问题在这里:

 var top = spawn('top'); top.stdout.on('data', function(data) { data_builder+=data.toString(); }); setTimeout(function() { top.kill(); callback(topparser.parse(data_builder,10)) },duration); 

你正在尝试使用超时这个不好的做法来调用callback。 相反,您可以从stdout.on('data')内部调用callback函数,从而确保函数被调用,并且在调用callback之前有数据可用。

像这样:

 top.stdout.on('data', function(data) { data_builder+=data.toString(); top.kill(); callback(topparser.parse(data_builder,10)) }); 

理想情况下,使用承诺将有助于使代码更具可读性和结构性。

错误清楚指向TypeError: Cannot read property 'cpu' of undefined

这意味着你的dataundefined 。 这里你没有从你的getTopData()获取数据。

你可以检查这两行data_builder+=data.toString();topparser.parse(data_builder,10)

添加一些控制台语句,你会明白的。

build议

在你的代码中保持一致。 某处您正在编写纯JavaScript语法并在ES6某处

养成遵循任何一种习惯。