在做数据平台fbp模块的数据展示的时候,数据流是:
盟友平台 -> 接口请求 -> 获取json数据解析 -> 写DB -> 从DB读取数据 -> 处理数据 -> 回传前端展示
获取json数据解析
模拟接口请求抓包返回的数据是:
{
"status": 200,
"msg": "success",
"data": {
"count": 39,
"issues": [
{
"id": "9455ec22",
"systemId": 11484,
"userId": "",
"email": null,
"wx": null,
"mobile": "18675859111",
"device": null,
"createdTime": 1480995710887,
"updatedTime": 1480995710887,
"channel": 18,
"type": 1,
"content": "测试一下",
"version": "1.9.11",
"platform": "Windows_7_Ultimate",
"status": 14,
"jiraId": null,
"appId": "",
"appName": "",
"title": "测试一下",
"firstReplyTime": null,
"productId": 8,
"isDelete": 0
},
{
"id": "e4b5c5be",
"systemId": 11483,
"userId": "",
"email": null,
"wx": null,
"mobile": "18645256635",
"device": null,
"createdTime": 1480994394110,
"updatedTime": 1480994394110,
"channel": 18,
"type": 1,
"content": "反馈建议来啦啦",
"version": "1.9.11",
"platform": "Windows%207%20Ultimate",
"status": 14,
"jiraId": null,
"appId": "",
"appName": "",
"title": "反馈建议来啦啦",
"firstReplyTime": null,
"productId": 8,
"isDelete": 0
},
]
}
}
使用http.get
返回值传给response
http.get(options, function(response) {
});
对response进行解析处理
http.get(options, function(response) {
//body数据格式为{"status":200,"msg":"success","data":{"count":2487,"issues":[{},{}]}
response.on('data ', function(body) {
var json_body = JSON.parse(body);
// 获得 products object
var json_data = json_body.data;
var json_issues = json_data.issues;
console.log(json_issues)
});
});
请求返回的数据,如果"issues":[{ },{ }]下{ }数据为2个或2个以下时可成功解析返回数据,但如果大于2个时,就返回
undefined:1
Unexpected end of output
怀疑大于2个时获取到的数据不是json格式或者部分数据被截取丢弃,故模拟请求返回"issues":[{ },{ }]下{ }数据为10个,在线解析获取的数据,该数据为json格式
网上有人说是因为比如 "channel": 18
,值为数字没有双引号引起,也有说数据太长解析的问题
接着找到问题的原因是: 数据没有接收完就执行了解析动作,结果肯定会出错。应该对数据进行组合,然后执行“end”事件,在data事件中将接收到的数据组合起来,在end事件中进行解析
代码如下:
http.get(options, function(response) {
//body数据格式为{"status":200,"msg":"success","data":{"count":2487,"issues":[{},{}]}
var body = '';
response.on('data', function(d) {
body += d;
});
response.on('end', function() {
var json_body = JSON.parse(body);
// 获得 products object
var json_data = json_body.data;
var json_issues = json_data.issues;
var dataResult = [];
for(var i = 0 ; i<json_issues.length;i++){
dataResult.push(json_issues[i]);
}
callback(dataResult);
// console.log(dataResult[0])
});
});
处理数据库请求返回数据
现在每个数据库请求函数传入参数:projectName
和 selectdate
数据库获取函数请求返回单个项目的值为:
因为不需要展示所有的 project,project分为主流和非主流的产品,非主流的project的
build,statusNew,statusPending,statusLegacy,statusReplied,statusClosed,statusOver
这些参数分别求和
非主流项目列表
var elseApp = [
'项目1',
'项目2',
'项目3',
'项目4',
'项目5',
'项目6',
'项目7',
'项目8',
'项目9',
]
使用 for 循环处理数据并求和,代码如下:
function _elseAppDo(selectdate,callback1){
var elseData_build = 0;
var elseData_statusNew = 0;
var elseData_statusPending = 0;
var elseData_statusLegacy = 0;
var elseData_statusReplied = 0;
var elseData_statusClosed = 0;
var elseData_statusOver = 0;
for(var i = 0 ; i<elseApp.length; i++ ){
getFBPData.projectFBPOneDay(elseApp[i],selectdate,function (err,data) {
elseData_build += parseInt(data[i].build);
elseData_statusNew += parseInt(data[i]['statusNew']);
elseData_statusPending += parseInt(data[i]['statusPending']);
elseData_statusLegacy += parseInt(data[i]['statusLegacy']);
elseData_statusReplied += parseInt(data[i]['statusReplied']);
elseData_statusClosed += parseInt(data[i]['statusClosed']);
elseData_statusOver += parseInt(data[i]['statusOver']);
callback(null,data);
});
}
}
发现求和在for循环内数据是OK的,在for循环外就所有的值都等于0,这是因为同步的问题,使用async.mapSeries
进行处理,如下:
function _elseAppDo(selectdate,callback1){
async.mapSeries(elseApp, function(elseAppName, callback) {
getFBPData.projectFBPOneDay(elseAppName,selectdate,function (err,data) {
callback(null,data);
});
},function(err, elseInfoData) {
callback1(elseInfoData);
});
}
然后对data对应参数数据相加处理,处理的代码如下
function DBElseAppFBPDataHundle(selectdate,callback) {
var elseData_build = 0;
var elseData_statusNew = 0;
var elseData_statusPending = 0;
var elseData_statusLegacy = 0;
var elseData_statusReplied = 0;
var elseData_statusClosed = 0;
var elseData_statusOver = 0;
_elseAppDo(selectdate,function (data) {
for(var i = 0 ; i < data.length;i++){
elseData_build += parseInt(data[i].build);
elseData_statusNew += parseInt(data[i]['statusNew']);
elseData_statusPending += parseInt(data[i]['statusPending']);
elseData_statusLegacy += parseInt(data[i]['statusLegacy']);
elseData_statusReplied += parseInt(data[i]['statusReplied']);
elseData_statusClosed += parseInt(data[i]['statusClosed']);
elseData_statusOver += parseInt(data[i]['statusOver']);
}
var elseAppFBPDataInfo = {
projectName: '非主要项目',
build: elseData_build,
statusNew: elseData_statusNew,
statusPending: elseData_statusPending,
statusLegacy: elseData_statusLegacy,
statusReplied: elseData_statusReplied,
statusClosed: elseData_statusClosed,
statusOver: elseData_statusOver
};
callback(elseAppFBPDataInfo);
});
}
在主项目和非主要项目结合处理时,发现如果对应的
build,statusNew,statusPending,statusLegacy,statusReplied,statusClosed,statusOver
这些参数使用的是:
data[0]、data[1]、data[2]、data[3]、data[4]、data[5]、data[6]
如果这样处理时,后续如果在中间插入其他参数时,会比较混乱,在可读性上也不好
可以将data数据做为一个对象,调用的时候可以 data[i].build
这样的使用