MongoDB / Javascript范围问题

我正在连接并使用Node / MongoDB进行插入,但由于范围问题,我无法从函数访问连接。 任何想法如何使'数据库'variables全球范围?

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) 

一般来说,只有连接一次,可能随着你的应用程序启动。 MongoLabs的专家告诉我,Mongo驱动程序至less会处理池中的事情。 请注意,这与您在Java中可能做的非常不同,例如将connect()返回的db值保存在某处,可能是全局或应用程序或常用的模块之一。 然后根据需要在RegisterUser,DeleteUser等中使用它

更多的节点问题真的,但可能值得的标签,因为它被问了一下。 所以你说有一个范围问题,你是正确的,因为variables是.connect()方法的callback函数的本地,并且在其他地方是不可见的。 一种方法是将所有的逻辑转储到callback函数中,所以不存在范围问题,但是您可能不希望这样做。

问“我如何设定一个全球”,也不是真正正确的做法。 那么不直接,因为有关于打破节点的“asynchronous”模式的一般有趣的事情。 因此,更好的方法是使用某种“单例”实例,在该实例中只设置一次连接,但这是“全局的”,否则可能“需要”用于应用程序的其他区域。

这里有一个“微不足道”的方法来演示,但有很多方法可以做同样的事情:

 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(); }); } ); 

因此,这里的小模型对象在.getDb()有一个单一的方法,并且一旦它build立,它也保持一个保存_db连接的私有variables。 该方法的基本逻辑是查看是否定义了_db ,并在那里build立与驱动程序的连接。 在连接callback中, _dbvariables被设置。

这里的另一件事是方法本身接受一个“callback”,所以这是你以后如何使用它的地方,在这里返回一个错误或者当前的连接。

最后一部分只是代码中实现的两个函数的演示。 在第一次调用中,连接到数据库的调用在进入提供的callback函数之前进行。

下次我们调用时,连接已经设置在私有variables中,所以数据只是返回,而不是再次build立连接。

实现这种事情有很多种方式,但这是遵循的基本逻辑模式。 还有很多其他的“helper”实现,它们包装了MongoDB驱动程序,使得这些事情变得简单,pipe理连接池并确保连接也适合你,因此即使你仍然坚持从下级司机基地做好自己的一切工作。

首先,只有当你有一个连接时,你才会注册用户,所以你需要在那里做什么工作……所以从连接范围内调用RegisterUser 。 如果你想在这个函数中使用db对象,你需要传入参数db

RegisterUsers(db, user, pass)

你可以在函数中使用db