为什么我在 node.js class 中得到未定义的实例?
Why am I getting undefined instance in node.js class?
我是 node.js 的新手。我正在尝试为 node.js class 定义一个构造函数,它基本上从 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);
}
});
}
});
};
我正在尝试在其他 class 中使用它,如下所示:
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 方法时,它都会说上面 class(即 ConnectionDriver)的 db 变量未定义。但是我可以看到 ConnectionDriver 构造函数正在正确执行并且与数据库的连接已正确打开并且 this.db=db1
也正在运行 executed.Am 我做错了什么?任何帮助将不胜感激
在撞了我的头并投资(浪费)了一整天之后。我意识到了这个问题。实际上 mongoClient.open()
调用是一个异步调用,我 return CollectionDriver 对象甚至在打开 db/getting 数据库实例之前。
我通过在构造函数外部打开 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 变量初始化为无效的)。想知道为什么会出现这种行为吗??
这已经得到回答,但我认为正确的答案是,this
在函数调用中被重新定义。在要打开的回调函数中,this 现在指向该函数。如果你在节点 4+ 上,解决这个问题的方法是使用 ES6 箭头函数。
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
然后按预期运行。
我是 node.js 的新手。我正在尝试为 node.js class 定义一个构造函数,它基本上从 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);
}
});
}
});
};
我正在尝试在其他 class 中使用它,如下所示:
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 方法时,它都会说上面 class(即 ConnectionDriver)的 db 变量未定义。但是我可以看到 ConnectionDriver 构造函数正在正确执行并且与数据库的连接已正确打开并且 this.db=db1
也正在运行 executed.Am 我做错了什么?任何帮助将不胜感激
在撞了我的头并投资(浪费)了一整天之后。我意识到了这个问题。实际上 mongoClient.open()
调用是一个异步调用,我 return CollectionDriver 对象甚至在打开 db/getting 数据库实例之前。
我通过在构造函数外部打开 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 变量初始化为无效的)。想知道为什么会出现这种行为吗??
这已经得到回答,但我认为正确的答案是,this
在函数调用中被重新定义。在要打开的回调函数中,this 现在指向该函数。如果你在节点 4+ 上,解决这个问题的方法是使用 ES6 箭头函数。
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
然后按预期运行。