我正在尝试用 express 编写一个 javascript 文件来与 postgresql 数据库对话。更准确地说,我想编写一个将 SQL 作为输入参数并返回字符串化 json 的函数。考虑到这些表的大小,我可以假设内存不是问题。这是为私营企业制作内部使用工具的有偿工作。
我最近的尝试涉及将值放入全局变量的查询回调,但即使那样仍然失败,因为最外层的函数在定义 json 字符串之前返回。相关代码如下:
var dbjson;
function callDB(q) {
pg.connect(connectionString, function(err, client, done) {
if (err) {
console.error('error fetching client from pool', err);
} else {
client.query(q, [], function(err, result) {
client.query('COMMIT');
done();
if (err) {
console.error('error calling query ' + q, err);
} else {
dbjson = JSON.stringify(result.rows);
console.log('1 ' + dbjson);
}
console.log('2 ' + dbjson);
});
console.log('3 ' + dbjson);
}
console.log('4 ' + dbjson);
});
console.log('5 ' + dbjson);
}
我测试中的 SQL 是 “select id from users”
。
相关的控制台输出是:
5 undefined
GET /db/readTable?table=users 500 405.691 ms - 1671
3 undefined
4 undefined
1 [{"id":1},{"id":2},{"id":3},{"id":4}]
2 [{"id":1},{"id":2},{"id":3},{"id":4}]
为什么控制台日志按它们的顺序出现? 它们的顺序是一致的。
我试图编写一个轮询循环来等待在调用者中使用 setTimeout 设置全局变量,然后在回调中清除超时但失败了,我认为,因为 javascript 是单线程的并且我的循环不允许其他事件进行。也许我做错了。
虽然我知道我可以让每个函数处理自己的数据库连接和错误日志记录,但我真的很讨厌重复相同的代码。
执行此操作的更好方法是什么?
我对 express 和 javascript 比较陌生,但对其他语言的经验要丰富得多。
最佳答案
以下行的存在将为您打破一切:
client.query('COMMIT');
您正在尝试以同步方式执行异步命令,并且您正在调用 done()
,在该查询有机会执行之前释放连接。这种无效断开连接的结果将是不可预测的,特别是因为在这种情况下您没有处理任何错误。
为什么首先要在那里调用 COMMIT
?这本身看起来完全无效。 COMMIT
用于关闭当前事务,您甚至没有在那里打开它,因此它不存在。
在异步代码使用和数据库方面存在一些误解。如果你想在这两个方面都有一个好的开始,我建议你看看 pg-promise .
关于Javascript事件序列,pg,postgresql,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30875223/