使用Node.js / node-postgres lib / PostgreDB实现RESTful服务有两个问题,两者都是由于JS的异步性质。
A)我需要将额外的参数传递给 client.query(查询,回调)调用中的回调
我在查询的回调中,并从数据库中查看最近获取的行数组,并希望为每个行启动后续查询:
var query = client.query('SELECT * FROM event', queryAllEventsHandler);
function queryAllEventsHandler(err, result){
allEvents = result.rows;
/* allEvents is an JSON array with the following format
[ {"id_event":1, "name":"name of the event"},
{"id_event":1, "name":"name of the event"}
]
*/
for(var i = 0; i<allEvents.length; i++){
client.query('SELECT * FROM days where id_event = $1',[allEvents[i].id_event], function( err, result){
//I want to have a reference to variable i
}
}
在上面的示例中,我想做类似的事情:
client.query('SELECT * FROM days where id_event = $1',[allEvents[i].id_event], function( AN_EXTRA_ARG, err, result)
AN_EXTRA_ARG是回调函数中的额外参数或闭包...如何实现?我应该使用 i 创建一个闭包并将其作为回调的arg传递吗?怎么样 ? :|
B)“同步”查询
我需要启动各种查询并从所有查询创建自定义JSON。因为每个查询和它的回调都是异步的(等待没有人)我正在寻找一种方法来“驯服”它以及其他一些东西我找到了一个首先出现在我身上的解决方案,但似乎有点“糟糕/糟糕” “: 保持查询计数是真正的方法,因为Synchronous database queries with Node.js中 @jslatts 建议?
希望我
答案 0 :(得分:1)
关于问题A,您可以创建一个函数来处理您的查询,并且只在最后一个查询执行时返回,并将两个结果都返回给回调。
for(var i = 0; i<allEvents.length; i++){
query(client, allEvents[i], function(result1, result2) {
//do something
});
}
function query(client, event, callback) {
client.query('SELECT * FROM days where id_event = $1',[event.id_event], function( err1, result1){
client.query('SELECT * FROM days where id_event = $1',[event.id_event], function( err2, result2){
callback(result1, result2);
});
});
}
答案 1 :(得分:1)
我不喜欢回答我的问题,但这可能是某些人感兴趣的......关于我问题的一部分。您可以在功能中为此指定自定义对象。
如果你知道一个关键字这个对应于一个函数内的Window(顶部)对象(除非它是一个方法函数)。使用bind函数,您可以将其引用更改为您自己的对象...
所以我做的是,我创建了一个命名函数 queryCallback
function queryCallback(err, result){
//this == Window (default)
}
将匿名回调函数更改为指定的 queryCallback :
client.query('SELECT * ... where id_event = $1',[allEvents[i].id_event], queryCallback.bind( {"position":i}, err, result));
现在,请注意 queryCallback.bind({“position”:i},err,result));
绑定(my_custom_this,[other args])的作用是将自定义对象(在我的情况下为“{position”:i})绑定到 this 绑定被称为的函数...
现在我们有了这个场景:
function queryCallback(err, result){
//this == {"position":i}
}
答案 2 :(得分:0)
A)我个人喜欢lodash(如果您愿意,可以使用下划线)partial()
。它接受一个函数和一些参数,并返回一个函数,其中应用了提供的参数,其余参数仍然打开。它非常像currying的功能概念。
B)为了组合多个异步结果,我强烈推荐async。语法需要一点点习惯,但这样做很容易。快速样本:
async.parallel([
one: function(callback){
db.fetch(options, callback);
},
two: function(callback){
db.fetch(options, callback);
}
],
function(err, results){
// this callback will get called when either parallel call gives an error
// or when both have called the callback
if (err) {
// handle error
return;
}
// get the results from results.one and results.two
});
==在edit ==
中添加实际上,lodash还为你的问题A)提供了一个更好的(imho)虽然略贵(由于函数调用)解决方案A):
_(allEvents).each(function(event, index, array) {
client.query('SELECT * FROM days where id_event = $1',[event.id_event], function( err, result) {
// Just use 'index' here, which doesn't change during the each
}
});
答案 3 :(得分:0)
对于B),您的选项包括异步或通过Promise库(例如Q,when.js,Bluebird等...)