我是node.js的新手。我正在尝试为node.js类定义一个构造函数,它基本上从mongo db中获取数据。相同的代码如下
var MongoClient = require('mongodb').MongoClient,
Server = require('mongodb').Server;
var ObjectID = require('mongodb').ObjectID;
var mongoHost = 'localHost';
var mongoPort = 27017;
CollectionDriver = function(db) {
this.db = db;
console.log("Collection drive has been set");
};
CollectionDriver = function() {
var mongoClient = new MongoClient(new Server(mongoHost, mongoPort));
mongoClient.open(function(err, mongoClient) {
if (!mongoClient || err) {
console.error("Error! Exiting... Must start MongoDB first");
process.exit(1);
}
var db1 = mongoClient.db("Quiz");
this.db = db1;
console.log("Set Collection Driver by default");
});
};
CollectionDriver.prototype.getCollection = function(collectionName, callback) {
this.db.collection(collectionName, function(error, the_collection) {
if (error) callback(error);
else callback(null, the_collection);
});
};
//find all objects for a collection
CollectionDriver.prototype.findAll = function(collectionName, obj, callback) {
this.getCollection(collectionName, function(error, the_collection) {
if (error) callback(error);
else {
the_collection.find(obj).toArray(function(error, results) {
if (error) callback(error);
else {
console.dir(results);
callback(null, results);
}
});
}
});
};
我试图在其他类中使用它,如下所示:
CollectionDriver = require('./collectionDriver').CollectionDriver;
var collectionDriver = new CollectionDriver(db);
OtherClassName.prototype.find = function(credentials, callback) {
collectionDriver.findAll("user_groups", credentials, function(error, results) {
if (!error) {
// Do something
}
});
// ...
每当我尝试访问Otherclass的find方法时,它都说上面的类的db变量(即ConnectionDriver)是未定义的。但是我可以看到ConnectionDriver构造函数正确执行并且正确打开了与db的连接,并且this.db=db1
也被执行了。我做错了什么?任何帮助将不胜感激
答案 0 :(得分:1)
在敲打我的头并投入(浪费)一整天之后。我意识到了这个问题。实际上mongoClient.open()
调用是一个异步调用,我甚至在打开db / getting db实例之前就返回了CollectionDriver对象。
我通过在构造函数外部移动db调用并设置实例db来解决了这个问题。修改后的代码如下:
var db = null;
var mongoClient = new MongoClient(new Server(mongoHost, mongoPort));
mongoClient.open(function(err, mongoClient) {
if (!mongoClient || err) {
console.error("Error! Exiting... Must start MongoDB first");
process.exit(1);
}
db = mongoClient.db("Quiz");
});
CollectionDriver = function() {
console.log("Set Collection Driver by default");
};
上面的代码似乎有效,但是当我将db实例分配给this.db
而不是如上所述明确声明变量时,我得到相同的undefined / null错误(当我将db变量初始化为null时)。有什么想法为什么这个行为?
答案 1 :(得分:0)
这已经回答了,但我相信正确的答案是,this
在函数调用中被重新定义。在要打开的回调函数内部,现在指向该函数。解决这个问题的方法是使用ES6箭头函数,如果你在节点4 +上。
collectionDriver = function() {
var mongoClient = new MongoClient(new Server(mongoHost, mongoPort));
mongoClient.open((err, mongoClient) => {
if (!mongoClient || err) {
console.error("Error! Exiting... Must start MongoDB first");
process.exit(1);
}
var db1 = mongoClient.db("Quiz");
this.db = db1;
console.log("Set Collection Driver by default");
});
注意:function (err, mongoClient) {
已更改为(err, mongoClient) => {
this
然后按预期行事。