0

我在使用 Node.js / node-postgres lib / PostgreDB 实现 RESTful 服务时遇到了两个问题,这两个问题都是由于 JS 的异步特性造成的。

A) 我需要在client.query(query, callback)调用中向回调传递一个额外的参数

我在查询的回调中,并通过最近从数据库中获取的行的数组,并希望为每个行启动后续查询:

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 是回调函数中的额外参数或闭包......我怎样才能实现这一点?我应该使用 of i创建一个闭包并将其作为回调的 arg 传递吗?如何 ?:|

B)“同步”查询

我需要启动各种查询并从所有查询中创建自定义 JSON。由于每个查询及其回调都是异步的(不等待任何人),我一直在寻找一种“驯服”它的方法,除此之外,我发现了一个首先出现在我身上的解决方案,但似乎有点“糟糕/糟糕” “:保持查询计数真的是@jslatts使用 Node.js 进行同步数据库查询中建议的方法吗?

希望我

4

4 回答 4

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);
        });
     });
}
于 2013-06-25T11:24:09.407 回答
1

我不喜欢回答我的问题,但这可能会引起某人的兴趣....关于我问题的 A 部分。您可以在函数中为此分配一个自定义对象。

如您所知,关键字this对应于函数内部的 Window(顶部)对象(除非它是方法函数)。使用 bind 函数,您可以将 this 的引用更改为您自己的对象...

所以我所做的是,我创建了一个命名函数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));

bind( my_custom_this , [other args])所做的是将自定义对象(在我的情况下为 {"position":i})绑定到调用绑定的函数内的this ...

现在我们有这样的场景:

function queryCallback(err, result){
            //this == {"position":i}
}

绑定解释: http: //fitzgeraldnick.com/weblog/26/

于 2013-06-25T11:59:04.943 回答
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
});

==在编辑中添加==

实际上 lodash 还为您的问题 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
     }
});
于 2013-06-25T11:04:45.707 回答
0

对于 B),您的选项包括异步或通过 Promise 库(例如 Q、when.js、Bluebird 等...)

于 2015-01-16T15:45:21.990 回答