我正在创建一个新的web服务,我发送一个带有JSON的curl命令,而JSON包含一个数组
[{tempid:1,email:abc@123,address:asd},{tempid:2,email:abc@12345,address:asd45},{tempid:3,email:abc@1234,address:asd4}]
现在当我传递并在mysql表中插入数组时,tempid只是为了向用户显示在数据库中生成的联系人ID的映射为tempid:1现在已插入,而在数据库中它有cid 120,就像这样对于tempid2和3,
但是当我试图向客户端显示更新的值时,它只显示一个值,最后一次更改不是整个更新的数组。因为connection.querry函数的异步性质,所以我需要帮助,这里是我的webservice
contactadd webservice - >
for(var i=0;i<=request.body.contact.length-1;i++)
{
if(request.body.contact[i].tempid)
{ var ardata=new Array();
var o=request.body.contact[i];
pair=Object.keys(o).map(function(a){ return [a, o[a]] });
AM.addcontact(pair,request.session.user,request.body.contact.length,function(e,o){
if(!o)
{
response.send('something went wrong'+e);
}
else
{
//response.send(o);
}
});
}
}
以下是database.js脚本中的更新功能 - &gt;
//ContactSync-addcontact module for database
exports.addcontact=function (arr,email,addnum,callback)
{
var counter=0;
var uid;
var data=new Array();
var showinsert=new Array();
var values=new Array();
var datatable=new Array();
var inserting=new Array();
var tempid=0;
connection.query('SELECT UID FROM user where email1="'+email.email+'"',function(err,rows,fields){
if(err)
{
throw err;
}
else
{
if(rows[0]!=undefined)
{
uid=rows[0]['UID'];
}
else
{
uid="no id in database";
}
}
});// get the UID of the inserting user
// make array of user provided data
for(var j=0;j<=arr.length-1;j++)
{
if(arr[j][0]!='tempid')
{
data.push(arr[j][0]);
}
else
{
tempid=arr[j][1];
}
}
connection.query('SELECT column_name FROM information_schema.columns where table_schema="webservice" AND table_name="usercontacts"',function(err,rows,fields){
if(err)
{
throw err;
}
else
{
for(var i=0;i<=rows.length-1;i++)
{
datatable.push(rows[i]['column_name']);
}
}
for(var k=0;k<=datatable.length-1;k++)
{
if(inArray(data[k],datatable))
{
inserting.push(data[k]);
}
}
if(inserting.length>0)
{
for(var z=0;z<=arr.length-1;z++)
{
if(inArray(arr[z][0],inserting))
{
values.push('"'+arr[z][1]+'"');
}
}
// Insert tempid values and data in the usercontacts table with inserting and values
connection.query('INSERT INTO usercontacts (cid,uid,'+inserting+') VALUES("","'+uid+'",'+values+')',function(err,rows,fields){
if(err)
{
throw err;
}
else
{
connection.query('SELECT * FROM usercontacts WHERE uid="'+uid+'" ORDER BY cid DESC LIMIT 0,'+addnum+'',function(err,rows,fields){
if(err)
{
throw err;
}
else
{ showinsert.push('temp-id: '+tempid+',cid:'+rows[0].cid+',uid:'+uid);
//for(var i=0;i<=inserting.length-1;i++)
forEach(inserting,function(row,index)
{
showinsert.push(inserting[index]+":"+values[index]);
counter+=1;
});
callback(null,showinsert);
}
});
}
});
//insertion finished
}
else
{
callback("Please Provide atleast one field to enter with tempid");
}
});
}
我只需要在已经插入的数组中插入所有回调并向用户显示该数组,请帮助,完全卡住然后只有我正在尝试StackOverflow。
感谢您阅读BTW
结束答案 0 :(得分:1)
我不确定具体问题是什么,但是您共享的代码存在一些问题,迟早会让您感到困惑。其中一个可能会导致您的问题。
竞争条件
如果查询SELECT UID FROM user where email1=
由于任何原因需要的时间超过其下方的SELECT column_name FROM information_schema.columns
那么您将没有变量uuid
的值,并且您的逻辑将失败。请记住,这些调用是非阻塞的,因此除非它们嵌套或使用其他流控制机制,否则不能依赖于另一个之前的完成(如@Tracker指出的那样,async很受欢迎)。
抓住边缘案例
在下面的行中,您将字符串值分配给uid
变量,然后继续使用该变量,即使它现在包含错误消息。
uid="no id in database";
这样做意味着稍后您的代码将无法做出反应。而是使用不同的变量,离开uid = undefined
或立即返回带有错误的回调,例如
return callback(new Error("user not found"));
举报错误
除非您想要终止进程,否则不要在Node中抛出错误,例如服务器启动期间的依赖问题它不像Java一样工作,异步错误不会被try / catch捕获,并且会导致您的进程被终止或让您处于难以理解的状态。而是将错误对象作为回调的第一个参数并立即返回,如下所示:
if ( err ) return callback(err);
然后在您的客户端代码中,您始终可以检查第一个参数以查看是否存在问题。
安全问题
正如@Tracker所提到的,不要这样做:
connection.query('SELECT UID FROM user where email1="'+email.email+'"', ...
如果变量的值以"; drop table user;
或类似方式传递,那么您就遇到了麻烦。相反,您可以像这样使用node-mysql的构建转义:
connection.query('SELECT UID FROM user where email1=?', [email.email], ...
<强>白名单强>
您正在查询information_schema.columns
,以便检测哪些字段有效,然后将其插入usercontacts
。这是一个聪明的技巧,但是将3个查询过程增加到4个查询,如果有任何字段不允许用户插入数据,则会引发问题。使用列白名单可能看起来要维护更多代码,但实际上比动态匹配列所需的所有代码更简单。
<强>阵列强>
我没有看到函数inArray()
的来源,但看起来它与Array.prototype.indexOf()
的作用相同,所以最好使用它。 e.g。
if ( datatable.indexOf(data[k]) > -1 ) inserting.push(data[k]);
您可以删除的每行自定义代码都是您不必维护的一行代码。