我正在使用node {js的node-postgres模块,我在插入数据时遇到问题。
功能:
function addItems(listId, listItems, handle) {
if (!listItems) {
handle(listId);
return;
}
var client = dbConnector.getClient(),
important,
dateArray,
dateString,
i,
prepStatement;
client.connect();
for (i in listItems) {
console.log(listItems[i]);
dateArray = listItems[i].itemdate.split('-');
dateString = dateArray[1] + '-' + dateArray[0] + '-' + dateArray[2];
if (listItems[i].important) {
important = 'true';
} else {
important = 'false';
}
prepStatement = {
name: 'insert task',
text: 'INSERT INTO listitem (todolist_id, name, deadline, description, important, done, created) VALUES ($1, $2, $3, $4, $5, $6, now()) RETURNING listitem_id',
values: [ listId, listItems[i].itemname, dateString, listItems[i].itemdesc, important, listItems[i].done ]
};
var query = client.query(prepStatement);
console.log("Adding item " + i);
query.on('error', function(error) {
console.log(error);
});
query.on('end', function(result) {
console.log("Query ended");
if (result) {
console.log("Added listitem no " + result.rows[0].listitem_id);
}
});
}
client.end();
handle(listId);
}
数据库中不会显示新数据。永远不会触发query.on('error')
和query.on('end')
事件。想一想,我开始怀疑查询是否被触发(因为我不明白为什么不应该这样)。
我得到的唯一日志是:
{ itemname: 'Task 1',
itemdate: '08-05-2012',
important: 'on',
itemdesc: 'A task',
done: 'false' }
Adding item 0
{ itemname: 'Task 2',
itemdate: '22-05-2012',
important: 'on',
itemdesc: 'Another one',
done: 'false' }
Adding item 1
那我该如何进行调试?
答案 0 :(得分:5)
在您的查询可以执行之前调用client.end()。 node-postgres不会抛出“未连接”错误,因为它旨在将查询排队,直到连接准备就绪。 https://github.com/brianc/node-postgres/wiki/Client#method-connect
试试这个:
function addItems(listId, listItems, handle) {
if (!listItems) {
handle(listId);
return;
}
var client = dbConnector.getClient(),
important,
dateArray,
dateString,
i,
prepStatement,
queryCount = 0;
client.connect();
for (i in listItems) {
console.log(listItems[i]);
dateArray = listItems[i].itemdate.split('-');
dateString = dateArray[1] + '-' + dateArray[0] + '-' + dateArray[2];
if (listItems[i].important) {
important = 'true';
} else {
important = 'false';
}
prepStatement = {
name: 'insert task',
text: 'INSERT INTO listitem (todolist_id, name, deadline, description, important, done, created) VALUES ($1, $2, $3, $4, $5, $6, now()) RETURNING listitem_id',
values: [ listId, listItems[i].itemname, dateString, listItems[i].itemdesc, important, listItems[i].done ]
};
var query = client.query(prepStatement);
queryCount++;
console.log("Adding item " + i);
query.on('error', function(error) {
console.log(error);
});
query.on('end', function(result) {
queryCount--;
console.log("Query ended");
if (result) {
console.log("Added listitem no " + result.rows[0].listitem_id);
}
if (queryCount === 0) {
client.end();
handle(listId);
}
});
}
}
以上所做的就是跟踪你发出的查询数量以及它们全部结束的时间,然后调用client.end()和handle(listId);
这可能是单调乏味且容易出错的,因此存在一些库以使asyc流更容易。我最喜欢的是异步,它可以在浏览器和节点中运行。 https://github.com/caolan/async
使用async,我会将代码重写为:
function addItems(listId, listItems, handle) {
if (!listItems) {
handle(listId);
return;
}
var client = dbConnector.getClient(),
important,
dateArray,
dateString,
i,
prepStatement;
client.connect();
async.forEach(
listItems,
// called for each listItems
function(listItem, callback){
console.log(listItem);
dateArray = listItem.itemdate.split('-');
dateString = dateArray[1] + '-' + dateArray[0] + '-' + dateArray[2];
if (listItem.important) {
important = 'true';
} else {
important = 'false';
}
prepStatement = {
name: 'insert task',
text: 'INSERT INTO listitem (todolist_id, name, deadline, description, important, done, created) VALUES ($1, $2, $3, $4, $5, $6, now()) RETURNING listitem_id',
values: [ listId, listItem.itemname, dateString, listItem.itemdesc, important, listItem.done ]
};
var query = client.query(prepStatement);
//console.log("Adding item " + i);
query.on('error', function(error) {
console.log(error);
callback(error),
});
query.on('end', function(result) {
console.log("Query ended");
if (result) {
console.log("Added listitem no " + result.rows[0].listitem_id);
}
callback(null,result);
});
},
// called after iterator function
function(err) {
if (err) return; // could use this as an err handler for all queries
client.end();
handle(listId);
}
);
};
另请参阅async.forEachSeries,但我认为在这种情况下不需要它,因为node-postgres客户端无论如何都将以串行方式运行查询。