使用参数和同步查询查询回调

时间:2013-06-25 10:50:30

标签: node.js node-postgres

使用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 建议?

希望我

4 个答案:

答案 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}
}

Bind解释:http://fitzgeraldnick.com/weblog/26/

答案 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等...)