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