node-postgres:查询未按顺序执行
node-postgres : query not executing in sequence
我根据条件在 2 个不同的文件中保留了插入和更新代码
总是插入应该先执行然后更新。但不知何故先执行更新然后插入
test.js : 简化代码
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 (,,)',[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 = ",[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 可以轻松解决这个问题。但是我的插入代码和更新代码在不同的文件中,根据某些情况,更新代码可能 execute.so 不想使用异步
问题
即使插入查询先执行为什么更新在输出中先完成
我是不是漏了什么..?
正如我已经提到的,确保 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 (,,)',[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 = ",[id], function(err, result) {
done();
if(err) { return console.error('error running query', err); }
console.log('finished executing Update query');
});
});
});
您缺少 pg.connect 和 client.query 的异步特性。对这些 return 的调用是一个回调,它在执行完成之前将控制传递给下一个表达式,因此具有 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 (,,)',[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 = ",[id], function (err, result) {
if (err) {
return console.error('error running query', err);
}
console.log('finished executing Update query');
done();
});
});
done();
});
});
但这很容易出现回调地狱。所以考虑让所有异步调用 return 成为一个承诺。看看bluebird. If you want an ORM that has built in promise based call, you can take a look at 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);
});
Lets solve this question step by step
你"stated so don't want to use async"图书馆
解决方案 1:
如果 PostgreSQL 使更新更快,更新将 return 在插入之前产生结果。如果您只想在完成插入后才开始执行更新查询,那么
you should set connection pool capacity to 1.
pg.defaults.poolSize = 1
但你应该在任何 pg.connect()
之前这样做
connect 方法从客户端池中检索一个 Client,或者如果所有池中的客户端都忙并且池未满,connect 方法将创建一个新的客户端,将其第一个参数直接传递给 Client 构造函数。在任何一种情况下,您提供的回调只会在客户端准备好发出查询或遇到错误时被调用。每次调用 connect 都会调用一次回调。
结论:您的查询将按顺序执行。但是但是但是这个解决方案是糟糕 用于扩展应用程序,因为始终只有一个连接为所有用户提供服务。因此,直到一个连接为一个用户提供服务,其他用户将不得不等待响应。
解决方案 2:
您还声明“我在 2 个不同的文件中保留了插入和更新代码”
看来您需要以能够使用 asynchronus 库的方式设计代码,这解决了这个问题
我根据条件在 2 个不同的文件中保留了插入和更新代码 总是插入应该先执行然后更新。但不知何故先执行更新然后插入
test.js : 简化代码
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 (,,)',[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 = ",[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 可以轻松解决这个问题。但是我的插入代码和更新代码在不同的文件中,根据某些情况,更新代码可能 execute.so 不想使用异步
问题
即使插入查询先执行为什么更新在输出中先完成
我是不是漏了什么..?
正如我已经提到的,确保 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 (,,)',[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 = ",[id], function(err, result) {
done();
if(err) { return console.error('error running query', err); }
console.log('finished executing Update query');
});
});
});
您缺少 pg.connect 和 client.query 的异步特性。对这些 return 的调用是一个回调,它在执行完成之前将控制传递给下一个表达式,因此具有 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 (,,)',[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 = ",[id], function (err, result) {
if (err) {
return console.error('error running query', err);
}
console.log('finished executing Update query');
done();
});
});
done();
});
});
但这很容易出现回调地狱。所以考虑让所有异步调用 return 成为一个承诺。看看bluebird. If you want an ORM that has built in promise based call, you can take a look at 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);
});
Lets solve this question step by step
你"stated so don't want to use async"图书馆
解决方案 1:
如果 PostgreSQL 使更新更快,更新将 return 在插入之前产生结果。如果您只想在完成插入后才开始执行更新查询,那么
you should set connection pool capacity to 1.
pg.defaults.poolSize = 1
但你应该在任何 pg.connect()
connect 方法从客户端池中检索一个 Client,或者如果所有池中的客户端都忙并且池未满,connect 方法将创建一个新的客户端,将其第一个参数直接传递给 Client 构造函数。在任何一种情况下,您提供的回调只会在客户端准备好发出查询或遇到错误时被调用。每次调用 connect 都会调用一次回调。
结论:您的查询将按顺序执行。但是但是但是这个解决方案是糟糕 用于扩展应用程序,因为始终只有一个连接为所有用户提供服务。因此,直到一个连接为一个用户提供服务,其他用户将不得不等待响应。
解决方案 2:
您还声明“我在 2 个不同的文件中保留了插入和更新代码”
看来您需要以能够使用 asynchronus 库的方式设计代码,这解决了这个问题