我保持插入&根据条件更新2个不同文件中的代码 总是插入应首先执行然后更新。但不知何故更新首先执行然后插入
var pg = require('pg');
var uuid = require('node-uuid').v4;
var id = uuid().toString();
var conString = 'postgres://postgres:pass@127.0.0.1:5432/testdb';
// ------INSERT
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');
});
});
tom@tom:~$node test.js
Executing Insert query
Executing update query
finished executing Update query //WHY UPDATE FINISHES FIRST
finished executing Insert query
使用async可以轻松解决此问题。但我的插入代码和更新代码位于不同的文件中,根据某些情况,更新代码可能会执行。所以不要使用异步
即使插入查询首先执行为什么更新在输出中首先完成
我错过了什么东西..?答案 0 :(得分:1)
正如我已经提到的,确保 update 函数仅在 insert 函数完成后才会触发的唯一方法是在 insert中调用它函数回调。这是asynchronous programming的基础知识。
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');
});
});
});
答案 1 :(得分:1)
让我们一步一步解决这个问题
你已经,所以不想使用async “库
解决方案1:
如果PostgreSQL更快地更新,更新将在插入之前返回结果。如果您想在完成插入后再开始执行更新查询
you should set connection pool capacity to 1.
pg.defaults.poolSize = 1
但您应该在任何pg.connect()
connect方法从客户端池中检索客户端,或者如果所有池化客户端都忙,并且池未满,则connect方法将创建一个新客户端,将其第一个参数直接传递给客户端构造函数。在任何一种情况下,只有在客户端准备发出查询或遇到错误时才会调用您提供的回调。每次调用connect时,都会调用一次回调函数。
结论:您的查询将按顺序执行。但是但此解决方案 BAD 用于扩展应用,因为始终只有一个连接为所有用户提供服务。因此,只有一个连接为一个用户服务,其他用户将不得不等待响应。
解决方案2:
您还说“我已将插入和更新代码保存在2个不同的文件中”
您似乎需要设计代码,以便能够使用asynchronus库来解决此问题
答案 2 :(得分:0)
您缺少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();
});
});
但这很容易被回调地狱。所以考虑让所有异步调用返回一个promise。看看bluebird。如果您想要一个内置基于承诺的呼叫的ORM,您可以查看sequelize。它对你来说可能很方便。
它的语法很简单:
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);
});