Node.js 节点postgres:查询未按顺序执行
我在两个不同的文件中根据条件保留了插入和更新代码 总是先执行insert,然后执行update。但不知何故,update先执行,然后执行insert test.js:简化代码 我正在使用这些软件包: 输出 注: 使用可以很容易地解决此问题。但是我的插入代码和更新代码位于不同的文件中,并且取决于某些情况,更新代码可能会执行。因此不希望使用异步 问题 即使Insert查询先执行为什么更新在输出中先完成Node.js 节点postgres:查询未按顺序执行,node.js,postgresql,node-postgres,Node.js,Postgresql,Node Postgres,我在两个不同的文件中根据条件保留了插入和更新代码 总是先执行insert,然后执行update。但不知何故,update先执行,然后执行insert test.js:简化代码 我正在使用这些软件包: 输出 注: 使用可以很容易地解决此问题。但是我的插入代码和更新代码位于不同的文件中,并且取决于某些情况,更新代码可能会执行。因此不希望使用异步 问题 即使Insert查询先执行为什么更新在输出中先完成 我遗漏了什么吗?正如我已经提到的,确保更新函数只有在插入函数完成后才会启动的唯一方法是在插入函数回
我遗漏了什么吗?正如我已经提到的,确保更新函数只有在插入函数完成后才会启动的唯一方法是在插入函数回调内部调用它。这是最基本的
您缺少pg.connect和client.query的异步特性。对这些函数的调用将返回一个回调,该回调在执行完成之前将控制传递给下一个表达式,从而实现nodejs的非阻塞性。如果要确保正确的流,可以调用回调成功中的后续流
var pg = require('pg');
var uuid = require('node-uuid').v4;
var id = uuid().toString();
// ------INSERT
return pg.connect;
// ------UPDATE
return pg.connect;
// your calling file
var insert = require('/path/to/insertfile');
var conString = 'postgres://postgres:pass@127.0.0.1:5432/testdb';
var update = require('/path/to/updatefile');
insert(conString, function (err, client, done) {
console.log('Executing Insert query');
client.query('insert into testdb (id,data,iscancelled) values ($1,$2,$3)',[id,'hello','no'], function (err, result) {
if (err) {
return console.error('error running query', err);
}
console.log('finished executing Insert query');
update(conString, function (error, client, done) {
console.log('Executing update query');
client.query("update testdb set iscancelled = 'yes' where id = $1",[id], function (err, result) {
if (err) {
return console.error('error running query', err);
}
console.log('finished executing Update query');
done();
});
});
done();
});
});
但这很容易成为地狱。因此,考虑所有的异步呼叫返回承诺。看一看。如果您想要一个内置了基于承诺的调用的ORM,您可以看看。对你来说可能很方便
它的语法非常简单:
var Model1 = require('/path/to/model1');
var Model2 = require('/path/to/model2');
var insertObj = {
"someKey": "value"
};
Model1.create(insertObj)
.then( function (createdObj1) {
return Model2.findOne({
where: {
"filter": "filterValue"
}
});
})
.then( function (documentToUpdate) {
return documentToUpdate.update({
"fieldToUpdate": "value"
});
})
.then( null, function (err) {
console.log(err);
});
让我们一步一步地解决这个问题
您“声明所以不想使用”库
解决方案1:
若PostgreSQL使更新更快,则更新将在插入之前返回结果。如果希望仅在完成插入后才开始执行更新查询,则
但是您应该在任何pg.connect()之前执行此操作
connect方法从客户机池检索客户机,或者如果所有池中的客户机都很忙且池未满,则connect方法将创建一个新客户机,并将其第一个参数直接传递给客户机构造函数。在这两种情况下,只有当客户端准备发出查询或遇到错误时,才会调用提供的回调。回调将被调用一次,并且每次调用connect时只调用一次
结论:您的查询将按顺序执行。但是此解决方案对于缩放应用程序来说是不好的,因为始终只有一个连接服务于所有用户。因此,在一个连接服务于一个用户之前,其他用户将不得不等待响应
解决方案2:
您还声明“我已将插入和更新代码保存在两个不同的文件中”
看起来您需要以这样一种方式设计代码,即您能够使用库,从而解决此问题您所说的“我的插入代码和更新代码在不同的文件中”是什么意思?它们是一个包含在另一个中的吗?将代码拆分为文件不会改变异步原则。如果要确保一致性,更新函数应该在插入回调中。它们不包括在彼此中,只需先触发插入,然后更新…并且根据代码,它们之间不相互依赖。此外,还有pg promise
模块。也许能帮你@plutopunch如果有人在帮助您,并且您发现答案很有帮助,请养成向上投票并选择合适答案的习惯。@Pravin您的答案显示异步行为..如我在问题中所述,我不想使用异步
pg.connect(conString, function(err, client, done) {
console.log('Executing Insert query');
client.query('insert into testdb (id,data,iscancelled) values ($1,$2,$3)',[id,'hello','no'], function(err, result) {
done();
if(err) { return console.error('error running query', err); }
console.log('finished executing Insert query');
// ------UPDATE
pg.connect(conString, function(err, client, done) {
console.log('Executing update query');
client.query("update testdb set iscancelled = 'yes' where id = $1",[id], function(err, result) {
done();
if(err) { return console.error('error running query', err); }
console.log('finished executing Update query');
});
});
});
var pg = require('pg');
var uuid = require('node-uuid').v4;
var id = uuid().toString();
// ------INSERT
return pg.connect;
// ------UPDATE
return pg.connect;
// your calling file
var insert = require('/path/to/insertfile');
var conString = 'postgres://postgres:pass@127.0.0.1:5432/testdb';
var update = require('/path/to/updatefile');
insert(conString, function (err, client, done) {
console.log('Executing Insert query');
client.query('insert into testdb (id,data,iscancelled) values ($1,$2,$3)',[id,'hello','no'], function (err, result) {
if (err) {
return console.error('error running query', err);
}
console.log('finished executing Insert query');
update(conString, function (error, client, done) {
console.log('Executing update query');
client.query("update testdb set iscancelled = 'yes' where id = $1",[id], function (err, result) {
if (err) {
return console.error('error running query', err);
}
console.log('finished executing Update query');
done();
});
});
done();
});
});
var Model1 = require('/path/to/model1');
var Model2 = require('/path/to/model2');
var insertObj = {
"someKey": "value"
};
Model1.create(insertObj)
.then( function (createdObj1) {
return Model2.findOne({
where: {
"filter": "filterValue"
}
});
})
.then( function (documentToUpdate) {
return documentToUpdate.update({
"fieldToUpdate": "value"
});
})
.then( null, function (err) {
console.log(err);
});
pg.defaults.poolSize = 1