Javascript 使用异步队列控制数据库连接请求

Javascript 使用异步队列控制数据库连接请求,javascript,node.js,Javascript,Node.js,我正在用Node和Mongodb Native构建一个应用程序。我正在开发一个db模块,我可以需要它并调用其他模块,这样我就可以只使用一个连接。模块db.js从以下代码开始: var _db = null; var getDb = module.exports.getDb = function(callback) { if (_db) { console.log('_db returned'); return callback(null, _db); } MongoC

我正在用Node和Mongodb Native构建一个应用程序。我正在开发一个db模块,我可以需要它并调用其他模块,这样我就可以只使用一个连接。模块
db.js
从以下代码开始:

var _db = null;
var getDb = module.exports.getDb = function(callback) {
  if (_db) {
    console.log('_db returned');
    return callback(null, _db);
  }
  MongoClient.connect('mongodb://localhost:' + config.db.port + '/' + config.db.name, {native_parser: true}, function (err, db) {
    if (err) return callback(err);
    console.log('_db created');

    _db = db;
    callback(err, _db);
    });
};
在其他需要db连接的模块中,我这样做

db.getDb(function (err, connection) {
  // Do something with connection
});
它很好用。但一个令人不快的问题是,如果我的代码在很短的时间跨度内多次调用
getDb
,我最终会得到一个连接的多个副本。例如,如果我在需要db连接的所有模块的最开始执行
db.js
要求和
getDb
调用

我现在正在考虑通过排队来控制对
getDb
的调用,这样只有绝对的第一个调用才会创建连接并将其保存在
\u db
中。所有以后的调用都将得到创建的连接
\u db
。我相信这会帮助我

问题在于我不明白如何使用异步队列编写此代码。文档有点模糊,我在网上找不到更好的例子。也许你能给我一些提示。这就是我到目前为止得到的

var dbCalls = async.queue(function (task, callback) {
  if (_db) {
    console.log('_db returned');
    return callback(null, _db);
  }
  MongoClient.connect('mongodb://localhost:' + config.db.port + '/' + config.db.name, {native_parser: true}, function (err, db) {
    if (err) return callback(err);
    console.log('Connected to mongodb://localhost:' + config.db.port + '/' + config.db.name);

    _db = db;
    callback(null, _db);
  });
}, 1);

// I guess this .push() must be the exposed (exported) API for other modules to get a connection, but how do I return it to them,  
dbCalls.push(null, function (err) {
  console.log('finished processing foo');
});

dbCalls.push(null, function (err) {
  console.log('finished processing bar');
});

我不理解作为第一个参数传递给
.push()
的对象,如果用于什么?现在它为空,我如何将连接和可能的错误一直传递到发出调用的模块

一个没有
async.queue的快速而肮脏的解决方案

var _db      = null;
var _err     = null;
var _queue   = [];
var _pending = false;

var getDb = module.exports.getDb = function(callback) {
  if (_err || _db) {
    console.log('_db returned');
    return callback(_err, _db);
  } else if (_pending) { // already a connect() request pending
    _queue.push(callback);
  } else {
    _pending = true;
    _queue.push(callback);
    MongoClient.connect(..., function (err, db) {
      _err = err;
      _db = db;
      _queue.forEach(function(queuedCallback) {
        queuedCallback(err, db);
      });
    });
};

谢谢我非常欣赏这种非依赖性的解决方案,因为它让我深入了解了像async(可能)这样的库在幕后是如何工作的!从长远来看,我认为知道如何用普通js解决问题将为您提供最好的服务!