【问题标题】:How to wait for N number of queries to finish before calling the callback function with Nodejs如何在使用Nodejs调用回调函数之前等待N个查询完成
【发布时间】:2016-07-23 00:05:07
【问题描述】:

我正在尝试创建一个查询数据库并返回对象列表的函数,对于每个对象我需要查询数据库并返回所有查询的结果。

如何等待所有查询完成,或者我应该以同步方式执行它们?如果是这样怎么办?我不应该利用它们都是选择查询并且不相互依赖的事实,因此并行运行它们以优化时间吗?这是一个糟糕的设计吗?或者我应该为此使用存储过程?

getTopActiveUsers:function(callback) {
    pool.connect(function (err, client, done) {
        if (err)
            callback(null, err);
        else {
            User.finAll(client,function(users) {
                for(var i=0;i<users.length;i++) {
                    Application.findByUser(users[i].id,function(applications) {
                        // here i have the applications for user i
                    })
                }
                // need to call the callback function when all queries finishes
            })
        }
    });
}

【问题讨论】:

    标签: javascript sql node.js postgresql promise


    【解决方案1】:

    async 库适合您。 parallel 方法并行执行所有请求,并等待它们全部完成。

    getTopActiveUsers : function(callback) {
    pool.connect(function(err, client, done) {
        if (err) {
            callback(null, err);
        } else {
            User.finAll(client, function(users) {
                var requests = [];
    
                for (var i = 0; i < users.length; i++) {
                    requests.push(function(asyncCallback) {
                        Application.findByUser(users[i].id, function(applications) {
                            // here i have the applications for user i
                            asyncCallback();
                        });
                    });
    
                }
    
                async.parallel(requests, function(err) {
                    // Requests are finished here
                });
            })
        }
    });
    }
    

    文档: http://caolan.github.io/async/

    【讨论】:

      【解决方案2】:

      由于这些都可以并行运行,使用现有代码的最简单方法就是保留一个计数器:

      getTopActiveUsers:function(callback) {
          pool.connect(function (err, client, done) {
              if (err)
                  callback(null, err);
              else {
                  User.findAll(client,function(users) {
                      var doneCnt = 0;
                      for(var i=0;i<users.length;i++) {
                          Application.findByUser(users[i].id,function(applications) {
                              // here i have the applications for user i
                              ++doneCnt;
                              if (doneCnt === users.length) {
                                  callback(null, someResult);
                              }
                          })
                      }
                  })
              }
          });
      }
      

      更高级(和更灵活)的机制是学习和使用基于 Promise 的数据库接口,然后您可以使用 Promise.all() 来跟踪何时完成多个异步操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-17
        • 1970-01-01
        • 2022-12-18
        • 1970-01-01
        • 2010-10-19
        相关资源
        最近更新 更多