Module.export一个'默认'函数

时间:2017-08-08 21:22:08

标签: node.js

我想编写一个导出默认函数和属性列表的模块(它们也是函数)。 基本上这个模块将允许消费者这种用法:

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()
@Igor Raush ES6 Class解决方案之后

编辑我写了这个,但仍然是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);
            });
        });
    }
}

2 个答案:

答案 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));
}