Javascript事件序列,pg,postgresql,为什么?

时间:2015-06-16 18:19:25

标签: javascript json postgresql express pg

我正在尝试在快递中写一个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是单线程的,我的循环不允许其他活动继续进行。也许我做错了。

虽然我知道我可以让每个函数处理自己的数据库连接和错误记录,但我真的很讨厌重复相同的代码。

有什么更好的方法可以做到这一点?

我对表达和javascript相对较新,但对其他语言有更多经验。

1 个答案:

答案 0 :(得分:0)

以下行的存在将为您打破一切:

client.query('COMMIT');

您正尝试以同步方式执行异步命令,并且在该查询有机会执行之前,您正在调用done(),释放连接。这种无效断开的结果将是不可预测的,特别是因为在这种情况下你没有处理任何错误。

为什么你首先在那里打COMMIT?这本身看起来完全无效。 COMMIT用于关闭当前事务,您甚至不在那里打开事务,因此它不存在。

在异步代码使用和数据库方面存在一些误解。如果你想两者都有一个良好的开端,我建议你看看pg-promise