Node.js 需要模块的异步问题

Node.js 需要模块的异步问题,node.js,promise,Node.js,Promise,我正在尝试创建一个mongoClient连接池模块,以便在我的项目中使用。问题是,当我第一次加载页面并调用mongoFactory时,似乎我的mongoConnection尚未建立。每隔一次,我加载页面后,它就可以正常工作了。我不知道我在这里遗漏了什么 这是我的mongoFactory.js /** * Creates and manages the Mongo connection pool * * @type {exports} */ var constants = require(

我正在尝试创建一个mongoClient连接池模块,以便在我的项目中使用。问题是,当我第一次加载页面并调用mongoFactory时,似乎我的mongoConnection尚未建立。每隔一次,我加载页面后,它就可以正常工作了。我不知道我在这里遗漏了什么

这是我的mongoFactory.js

/**
 * Creates and manages the Mongo connection pool
 *
 * @type {exports}
 */
var constants = require('../js/constants.js');
var Q = require('q');
var MongoClient = require('mongodb').MongoClient;
var db = null;

var getDb = function() {

  console.log('db = '+db);
  // If the connection pool has not been created or has been closed, create it, else return an existing connection
  if (db === null) {

    var def = Q.defer();

    // Initialize connection once
    MongoClient.connect(constants.mongoUrl, function (err, database) {
      if (err) {
        def.reject(err);
        throw err;
      }

      console.log('inside connection');
      db = database;
      def.resolve();
    });

    def.promise.then(function () {
      console.log('before returning connection');
      return db;
    });
  } else {
    console.log('connection already exists. returning');
    return db;
  }
}

module.exports.getDb = getDb;
这是我的档案我打电话给mongoFactory

var mongoFactory = require('../../lib/mongoFactory');

module.exports = function() {

  return {

    find: function find(callback) {

      var db = mongoFactory.getDb();
      var cases = db.collection('mycollection'); // <-- First time i load the page, errors b/c db is undefined. Every other time after that it works just fine. ERROR: TypeError: Uncaught error: Cannot call method 'collection' of undefined
...
var mongoFactory=require('../../lib/mongoFactory');
module.exports=函数(){
返回{
find:函数find(回调){
var db=mongoFactory.getDb();

var cases=db.collection('mycollection');//
MongoClient.connect
本质上是异步的,为什么不以nodejs的方式进行呢?我会更改您的
getDb
签名以接受回调:

var getDb = function(callback) {
  console.log('db = '+db);
  // If the connection pool has not been created or has been closed, create it, else return an existing connection
  if (db === null) {

    // Initialize connection once
    MongoClient.connect(constants.mongoUrl, function (err, database) {
      if (err) {
        callback(err);
        return;
      }

      console.log('inside connection');
      db = database;
      callback(null, db);
    });
  } else {
    console.log('connection already exists. returning');
    callback(null, db);
  }
}
find: function find(callback) {
  return mongoFactory.getDb().then(function(db) {
    // db is always available in the promise callback
    var cases = db.collection('mycollection');
    // return a promise or a value from the callback
  }); // and find will return a promise for that value
}
那么您的消费者必须:

mongoFactory.getDb(function(err, db) {
  if (err) {
     // handle error
  }
  var cases = db.collection('mycollection');
});

MongoClient.connect
本质上是异步的,为什么不以nodejs的方式进行呢?我会更改您的
getDb
签名以接受回调:

var getDb = function(callback) {
  console.log('db = '+db);
  // If the connection pool has not been created or has been closed, create it, else return an existing connection
  if (db === null) {

    // Initialize connection once
    MongoClient.connect(constants.mongoUrl, function (err, database) {
      if (err) {
        callback(err);
        return;
      }

      console.log('inside connection');
      db = database;
      callback(null, db);
    });
  } else {
    console.log('connection already exists. returning');
    callback(null, db);
  }
}
find: function find(callback) {
  return mongoFactory.getDb().then(function(db) {
    // db is always available in the promise callback
    var cases = db.collection('mycollection');
    // return a promise or a value from the callback
  }); // and find will return a promise for that value
}
那么您的消费者必须:

mongoFactory.getDb(function(err, db) {
  if (err) {
     // handle error
  }
  var cases = db.collection('mycollection');
});

MongoClient.connect
本质上是异步的,为什么不以nodejs的方式进行呢?我会更改您的
getDb
签名以接受回调:

var getDb = function(callback) {
  console.log('db = '+db);
  // If the connection pool has not been created or has been closed, create it, else return an existing connection
  if (db === null) {

    // Initialize connection once
    MongoClient.connect(constants.mongoUrl, function (err, database) {
      if (err) {
        callback(err);
        return;
      }

      console.log('inside connection');
      db = database;
      callback(null, db);
    });
  } else {
    console.log('connection already exists. returning');
    callback(null, db);
  }
}
find: function find(callback) {
  return mongoFactory.getDb().then(function(db) {
    // db is always available in the promise callback
    var cases = db.collection('mycollection');
    // return a promise or a value from the callback
  }); // and find will return a promise for that value
}
那么您的消费者必须:

mongoFactory.getDb(function(err, db) {
  if (err) {
     // handle error
  }
  var cases = db.collection('mycollection');
});

MongoClient.connect
本质上是异步的,为什么不以nodejs的方式进行呢?我会更改您的
getDb
签名以接受回调:

var getDb = function(callback) {
  console.log('db = '+db);
  // If the connection pool has not been created or has been closed, create it, else return an existing connection
  if (db === null) {

    // Initialize connection once
    MongoClient.connect(constants.mongoUrl, function (err, database) {
      if (err) {
        callback(err);
        return;
      }

      console.log('inside connection');
      db = database;
      callback(null, db);
    });
  } else {
    console.log('connection already exists. returning');
    callback(null, db);
  }
}
find: function find(callback) {
  return mongoFactory.getDb().then(function(db) {
    // db is always available in the promise callback
    var cases = db.collection('mycollection');
    // return a promise or a value from the callback
  }); // and find will return a promise for that value
}
那么您的消费者必须:

mongoFactory.getDb(function(err, db) {
  if (err) {
     // handle error
  }
  var cases = db.collection('mycollection');
});

您的
mongoFactory.getDb
应该返回一个承诺,该承诺将在连接建立后实现(第一次需要一段时间,之后将立即实现)

以及使用:

var mongoFactory = require( './mongoFactory' );
var con = mongoFactory.getDb();

con.done( function(db) {
    // use db here
} );

con.fail( function(err) {
   // error occurred
} );

您可能希望签出节点mongodb native周围的承诺包装器。

您的
mongoFactory.getDb
应返回一个承诺,该承诺将在连接建立后立即实现(第一次需要一段时间,之后将立即实现)

以及使用:

var mongoFactory = require( './mongoFactory' );
var con = mongoFactory.getDb();

con.done( function(db) {
    // use db here
} );

con.fail( function(err) {
   // error occurred
} );

您可能希望签出节点mongodb native周围的承诺包装器。

您的
mongoFactory.getDb
应返回一个承诺,该承诺将在连接建立后立即实现(第一次需要一段时间,之后将立即实现)

以及使用:

var mongoFactory = require( './mongoFactory' );
var con = mongoFactory.getDb();

con.done( function(db) {
    // use db here
} );

con.fail( function(err) {
   // error occurred
} );

您可能希望签出节点mongodb native周围的承诺包装器。

您的
mongoFactory.getDb
应返回一个承诺,该承诺将在连接建立后立即实现(第一次需要一段时间,之后将立即实现)

以及使用:

var mongoFactory = require( './mongoFactory' );
var con = mongoFactory.getDb();

con.done( function(db) {
    // use db here
} );

con.fail( function(err) {
   // error occurred
} );

您可能希望签出节点mongodb native周围的承诺包装器。

在函数中构造延迟不会自动使其阻塞-事实上它不能

db==null
的情况下,您的函数确实不返回任何内容(即
undefined
),并且仅在数据库连接已经通过以前的调用建立的情况下返回该连接。相反,它应该始终返回表示(可能稍后到达的)最终连接的承诺

/**
 * Creates and manages the Mongo connection pool
 *
 * @type {exports}
 */
var constants = require('../js/constants.js');
var Q = require('q');
var MongoClient = require('mongodb').MongoClient;
var dbPromise = null;

module.exports.getDb = function getDb() {
  // If the connection pool has been created or is being created, return the existing promise for that, else create it and return the promise for that
  if (dbPromise === null) {
    var def = Q.defer();

    // Initialize connection once
    MongoClient.connect(constants.mongoUrl, function (err, database) {
      if (err)
        def.reject(err);
      else
        def.resolve(database); // let the database be the result value of the promise!
    });
    return dbPromise = def.promise;
  } else {
    return dbPromise;
  }
};
现在函数返回了一个承诺,您需要在
然后
回调中使用它:

var getDb = function(callback) {
  console.log('db = '+db);
  // If the connection pool has not been created or has been closed, create it, else return an existing connection
  if (db === null) {

    // Initialize connection once
    MongoClient.connect(constants.mongoUrl, function (err, database) {
      if (err) {
        callback(err);
        return;
      }

      console.log('inside connection');
      db = database;
      callback(null, db);
    });
  } else {
    console.log('connection already exists. returning');
    callback(null, db);
  }
}
find: function find(callback) {
  return mongoFactory.getDb().then(function(db) {
    // db is always available in the promise callback
    var cases = db.collection('mycollection');
    // return a promise or a value from the callback
  }); // and find will return a promise for that value
}

在函数内部构造一个延迟函数并不会自动使其阻塞-事实上它不能

db==null
的情况下,您的函数确实不返回任何内容(即
undefined
),并且仅在数据库连接已经通过以前的调用建立的情况下返回该连接。相反,它应该始终返回表示(可能稍后到达的)最终连接的承诺

/**
 * Creates and manages the Mongo connection pool
 *
 * @type {exports}
 */
var constants = require('../js/constants.js');
var Q = require('q');
var MongoClient = require('mongodb').MongoClient;
var dbPromise = null;

module.exports.getDb = function getDb() {
  // If the connection pool has been created or is being created, return the existing promise for that, else create it and return the promise for that
  if (dbPromise === null) {
    var def = Q.defer();

    // Initialize connection once
    MongoClient.connect(constants.mongoUrl, function (err, database) {
      if (err)
        def.reject(err);
      else
        def.resolve(database); // let the database be the result value of the promise!
    });
    return dbPromise = def.promise;
  } else {
    return dbPromise;
  }
};
现在函数返回了一个承诺,您需要在
然后
回调中使用它:

var getDb = function(callback) {
  console.log('db = '+db);
  // If the connection pool has not been created or has been closed, create it, else return an existing connection
  if (db === null) {

    // Initialize connection once
    MongoClient.connect(constants.mongoUrl, function (err, database) {
      if (err) {
        callback(err);
        return;
      }

      console.log('inside connection');
      db = database;
      callback(null, db);
    });
  } else {
    console.log('connection already exists. returning');
    callback(null, db);
  }
}
find: function find(callback) {
  return mongoFactory.getDb().then(function(db) {
    // db is always available in the promise callback
    var cases = db.collection('mycollection');
    // return a promise or a value from the callback
  }); // and find will return a promise for that value
}

在函数内部构造一个延迟函数并不会自动使其阻塞-事实上它不能

db==null
的情况下,您的函数确实不返回任何内容(即
undefined
),并且仅在数据库连接已经通过以前的调用建立的情况下返回该连接。相反,它应该始终返回表示(可能稍后到达的)最终连接的承诺

/**
 * Creates and manages the Mongo connection pool
 *
 * @type {exports}
 */
var constants = require('../js/constants.js');
var Q = require('q');
var MongoClient = require('mongodb').MongoClient;
var dbPromise = null;

module.exports.getDb = function getDb() {
  // If the connection pool has been created or is being created, return the existing promise for that, else create it and return the promise for that
  if (dbPromise === null) {
    var def = Q.defer();

    // Initialize connection once
    MongoClient.connect(constants.mongoUrl, function (err, database) {
      if (err)
        def.reject(err);
      else
        def.resolve(database); // let the database be the result value of the promise!
    });
    return dbPromise = def.promise;
  } else {
    return dbPromise;
  }
};
现在函数返回了一个承诺,您需要在
然后
回调中使用它:

var getDb = function(callback) {
  console.log('db = '+db);
  // If the connection pool has not been created or has been closed, create it, else return an existing connection
  if (db === null) {

    // Initialize connection once
    MongoClient.connect(constants.mongoUrl, function (err, database) {
      if (err) {
        callback(err);
        return;
      }

      console.log('inside connection');
      db = database;
      callback(null, db);
    });
  } else {
    console.log('connection already exists. returning');
    callback(null, db);
  }
}
find: function find(callback) {
  return mongoFactory.getDb().then(function(db) {
    // db is always available in the promise callback
    var cases = db.collection('mycollection');
    // return a promise or a value from the callback
  }); // and find will return a promise for that value
}

在函数内部构造一个延迟函数并不会自动使其阻塞-事实上它不能

db==null
的情况下,您的函数确实不返回任何内容(即
undefined
),并且仅在数据库连接已经通过以前的调用建立的情况下返回该连接。相反,它应该始终返回表示(可能稍后到达的)最终连接的承诺

/**
 * Creates and manages the Mongo connection pool
 *
 * @type {exports}
 */
var constants = require('../js/constants.js');
var Q = require('q');
var MongoClient = require('mongodb').MongoClient;
var dbPromise = null;

module.exports.getDb = function getDb() {
  // If the connection pool has been created or is being created, return the existing promise for that, else create it and return the promise for that
  if (dbPromise === null) {
    var def = Q.defer();

    // Initialize connection once
    MongoClient.connect(constants.mongoUrl, function (err, database) {
      if (err)
        def.reject(err);
      else
        def.resolve(database); // let the database be the result value of the promise!
    });
    return dbPromise = def.promise;
  } else {
    return dbPromise;
  }
};
现在函数返回了一个承诺,您需要在
然后
回调中使用它:

var getDb = function(callback) {
  console.log('db = '+db);
  // If the connection pool has not been created or has been closed, create it, else return an existing connection
  if (db === null) {

    // Initialize connection once
    MongoClient.connect(constants.mongoUrl, function (err, database) {
      if (err) {
        callback(err);
        return;
      }

      console.log('inside connection');
      db = database;
      callback(null, db);
    });
  } else {
    console.log('connection already exists. returning');
    callback(null, db);
  }
}
find: function find(callback) {
  return mongoFactory.getDb().then(function(db) {
    // db is always available in the promise callback
    var cases = db.collection('mycollection');
    // return a promise or a value from the callback
  }); // and find will return a promise for that value
}


不使用承诺,但相关:类似是的,但我不认为完全相同。从我所读到的,
require
是同步的,因此我认为required mongoFactory.js将在执行下一行之前完成。是的,
getDb
是“不同步”的因此,它应该返回一个承诺,而不是db(如果它需要连接到mongo,它就不能同步执行)。但是我在getDb()函数中有一个承诺,所以在该承诺得到解决之前它不会返回吗?不,
return db
是从传递给
def.promise.then()的匿名函数返回的
不是来自
getDb
。如果您的代码流进入
db==null
,函数将不返回任何内容。不使用承诺,但相关:类似的是,但我认为不完全相同。据我所知,
require
是同步的,因此我认为required mongoFactory.js将在下一行完成之前完成是的,你的
getDb
就是