我想编写一个导出默认函数和属性列表的模块(它们也是函数)。 基本上这个模块将允许消费者这种用法:
let db_connection = fake_database_connection_instance()
let db = require('./db.js')(db_connection)
db.find({id:1})
因此默认函数应该只将数据库连接实例传递给模块。 这是无效的代码
module.exports = {
//init should go away and replaced by a 'default' function when this module is called
init: function (connection) {
this.connection= connection;
return this;
},
find: function (query) {
return new Promise(function (resolve, reject) {
this.connection.find(query, function (err, docs) {
if (err) {
return reject(err);
}
return resolve(docs);
});
});
}
}
我想避免new
关键字(消费者方),所以我必须删除this
,我知道。这里的问题是2:
require('./db.js')()
上调用的默认函数以及其他函数,例如require('./db.js').find()
?find()
? 编辑我写了这个,但仍然是db is not defined
class DB {
constructor(db) {
this.db = db;
}
find(query) {
return new Promise( (resolve, reject) => {
this.db.find(query, function (err, docs) {
if (err) {
return reject(err);
}
return resolve(docs);
});
});
}
}
答案 0 :(得分:4)
您可以向module.exports
添加默认功能,并使用外部变量_conn
存储连接:
let _conn;
module.exports = (connection) => {
_conn = connection;
};
之后,您可以将find
函数添加到module.exports
对象:
module.exports.find = (query) => {
return new Promise(function(resolve, reject) {
_conn.find(query, function(err, docs) {
if (err) {
return reject(err);
}
resolve(docs);
});
});
}
答案 1 :(得分:2)
一种选择是创建一个类并导出实例工厂函数。
// db.js
function DB(connection) {
this.connection = connection;
}
DB.prototype.find = function find(query) {
let connection = this.connection;
// ...
}
// export instance factory function
module.exports = function (connection) { return new DB(connection); };
或者,如果您在ES6环境中,
// db.js
class DB {
constructor(connection) {
this.connection = connection;
}
find(query) {
let connection = this.connection;
// ...
}
}
// export instance factory function
module.exports = connection => new DB(connection);
然后你可以做
let db = require('./db')(db_connection);
db.find({ id: 1 });
如果您想强制执行单例模式(只能存在一个DB
实例),则懒惰地创建一个模块本地实例并在后续调用中返回引用:
let _instance = null;
module.exports = connection => {
// return existing instance, or create a new one
return _instance || (_instance = new DB(connection));
}