MongoDB/Javascript范围问题
我正在连接Node/MongoDB并进行插入,但由于作用域问题,我无法从函数访问连接。知道如何使“db”变量成为全局范围吗MongoDB/Javascript范围问题,javascript,node.js,mongodb,node-mongodb-native,Javascript,Node.js,Mongodb,Node Mongodb Native,我正在连接Node/MongoDB并进行插入,但由于作用域问题,我无法从函数访问连接。知道如何使“db”变量成为全局范围吗 mongodb.connect("mongodb://localhost:27017/userDB", function(err, db) { if(!err) { console.log("We are connected"); } else { console.log(err); } }); function Regi
mongodb.connect("mongodb://localhost:27017/userDB", function(err, db) {
if(!err) {
console.log("We are connected");
} else {
console.log(err);
}
});
function RegisterUser(user, pass) {
var collection = db.collection('users');
var docs = [{username:user}, {password: pass}];
collection.insert(docs, {w:1}, function(err, result) {
collection.find().toArray(function(err, items) {});
socket.emit('message', items);
});
}
/var/www/baseball/app.js:80
var collection = db.collection('users'); <--db is not defined
^
ReferenceError: db is not defined
at RegisterUser (/var/www/baseball/app.js:80:20)
at ParseData (/var/www/baseball/app.js:63:6)
mongodb.connect(“mongodb://localhost:27017/userDB,函数(err,db){
如果(!err){
log(“我们已连接”);
}否则{
控制台日志(err);
}
});
函数注册器(用户,通过){
var collection=db.collection(“用户”);
var docs=[{username:user},{password:pass}];
insert(docs,{w:1},函数(err,result){
collection.find().toArray(函数(err,items){});
发出('message',项);
});
}
/var/www/barball/app.js:80
var collection=db.collection(“用户”) 首先,你只有在建立了连接后才能注册用户,所以你需要在那里做些什么呢。。。因此,在连接范围内调用RegisterUser
。如果要在该函数中使用db对象,则需要将参数作为db传入
RegisterUsers(数据库、用户、通行证)
然后,您可以在函数中使用db,一般情况下,只进行一次连接,可能是在应用程序启动时。mongo驱动程序将处理池等,至少,蒙古ABS的专家告诉我。请注意,这与您在Java中可能执行的操作非常不同,等等。。。将connect()返回的db值保存在某个位置,可能是全局或应用程序内,也可能是常用的模块中。然后根据需要在RegisterUser、DeleteUser等中使用它。这实际上是一个节点问题,但可能值得一提,因为它会被询问一点。因此,您说存在范围问题,您是对的,因为变量是.connect()
方法上回调函数的本地变量,在其他任何地方都不可见。一种方法是在回调中转储所有逻辑,这样就没有范围问题,但您可能不想这样做
问“我如何设置一个全球范围”,也不是真正正确的方法。当然不是直接的,因为打破节点的“异步”模式有很多有趣的事情。因此,更好的方法是使用某种“单例”实例,在该实例中,您只设置了一次连接,但这是全局性的,或者在应用程序的其他区域使用时可能是“必需的”
这里有一个“简单”的方法可以演示,但有很多方法可以实现同样的效果:
var async = require('async'),
mongodb = require('mongodb'),
MongoClient = mongodb.MongoClient;
var Model = (function() {
var _db;
var conlock;
return {
getDb: function(callback) {
var err = null;
if ( _db == null && conlock == null ) {
conlock = 1;
MongoClient.connect('mongodb://localhost/test',function(err,db) {
_db = db;
conlock == null;
if (!err) {
console.log("Connected")
}
callback(err,_db);
});
} else if ( conlock != null ) {
var count = 0;
async.whilst(
function() { return ( _db == null ) && (count < 5) },
function(callback) {
count++
setTimeout(callback,500);
},
function(err) {
if ( count == 5 )
err = new Error("connect wait exceeded");
callback(err,_db);
}
);
} else {
callback(err,_db);
}
}
};
})();
async.parallel(
[
function(callback) {
console.log("call model");
Model.getDb(function(err,db) {
if (err) throw err;
if (db != undefined)
console.log("db is defined");
callback();
});
},
function(callback) {
console.log("call model again");
Model.getDb(function(err,db) {
if (err) throw err;
if (db != undefined)
console.log("db is defined here as well");
callback();
})
}
],
function(err) {
Model.getDb(function(err,db) {
db.close();
});
}
);
var async=require('async'),
mongodb=require('mongodb'),
MongoClient=mongodb.MongoClient;
var模型=(函数(){
var_-db;
var-conlock;
返回{
getDb:函数(回调){
var err=null;
if(_db==null&&conlock==null){
conlock=1;
MongoClient.connect('mongodb://localhost/test,函数(err,db){
_db=db;
conlock==null;
如果(!err){
控制台日志(“已连接”)
}
回调(err,_db);
});
}else if(conlock!=null){
var计数=0;
异步的(
函数(){return(_db==null)&&(count<5)},
函数(回调){
计数++
setTimeout(回调,500);
},
功能(err){
如果(计数=5)
err=新错误(“超出连接等待”);
回调(err,_db);
}
);
}否则{
回调(err,_db);
}
}
};
})();
异步并行(
[
函数(回调){
log(“调用模型”);
Model.getDb(函数(err,db){
如果(错误)抛出错误;
如果(db!=未定义)
console.log(“定义了数据库”);
回调();
});
},
函数(回调){
log(“再次调用模型”);
Model.getDb(函数(err,db){
如果(错误)抛出错误;
如果(db!=未定义)
log(“这里也定义了db”);
回调();
})
}
],
功能(err){
Model.getDb(函数(err,db){
db.close();
});
}
);
因此,这里的out小“Model”对象在.getDb()
中有一个方法,并且它还维护一个私有变量,在建立连接后保存\u db
连接。该方法的基本逻辑是查看是否定义了\u db
,以及在哪里没有与驱动程序建立连接。然后在连接回调上设置\u db
变量
这里的另一件事是该方法本身接受一个“回调”,因此这就是您以后使用它的方式,其中将返回一个错误或当前连接
最后一部分只是要在代码中实现的两个函数的演示。其中,在第一次调用中,先调用连接到数据库的调用,然后再调用提供的回调函数
不过,下次调用时,连接已经在私有变量中设置好了,因此只返回数据,而不会再次建立连接
实现这类事情有多种方法,但这是要遵循的基本逻辑模式。还有许多其他的“帮助器”实现包装MongoDB驱动程序,使这些事情变得简单,管理连接池并确保连接对您来说也是正常的,因此,即使您仍然坚持自己从较低级别的驱动程序库中完成所有工作,也很值得一看。My bad,我刚刚在回调之外声明了一个全局var global_db。我以为我试过了,但没用,但我又试了一次,真的成功了,谢谢。从长远来看,你可能需要做一些更复杂的事情,就像尼尔的回答一样,你可能不想要一个全球性的,但至少你已经开始了。见回答1中的评论。我很感谢您的详细工作,但它很简单,只需在回调外部声明一个全局(窗口)变量,并将本地db对象设置为该全局变量即可。谢谢