Node.js模块通过接口导出

我有一个这样的模块:(其中文件夹前缀-和文件与|

 - MyModule |index.js - Lib |database.js |register.js |table.js 

index.js文件应该是一个接口文件,它提供了模块的api,在Lib中…

所以我的index.js看起来像这样:

 var register = require('./lib/register'); var table = require('./lib/table'); module.exports = { register : register.addNewUser, createNewTable : table.createTable, dropTable : table.dropTable } 

所以我可以在我的应用程序中调用我的模块:

 var myModule = require('./myModule'); 

然后例如:

 myModule.register; //registers a new user... 

特别的是database.js 。 它看起来像这样:

 var mysql = require('mysql'); module.exports = { createPool: function(options) { console.log('creating Pool ...') return module.exports.pool = mysql.createPool(options); } } 

它创build一个mysql池( 与geisendoerfers MySQL模块 ),并使该池可以访问我的模块中的其他文件:

 var pool = require('./database').pool; 

它曾经在app.js启动:

 var options = { host : 'host', user : 'user', password : 'pwd', database : 'database' } var makePool = require('./MyModule/lib/database').createPool(options); 

这工作正常!
但是现在我试图在index.js文件中得到函数createPool ,所以我可以调用

 var options = {...} var makePool = require('./MyModule').createPool(options); 

我在index.js中用这种方法试了这个:

 var database = require('./lib/database'); var register = require('./lib/register'); var table = require('./lib/table'); module.exports = { createPool : database.createPool, register : register.addNewUser, createNewTable : table.createTable, dropTable : table.dropTable } 

现在对我来说很奇怪 这应该在App.js中工作:

 var options = {...} var makePool = require('./myModule').createPool(options); var pool = require('./myModule/lib/database').pool; pool.getConnection(function(err, connection){ connection.query('SELECT 12 + 8 AS solution', function(err, result){ console.log(result); connection.release(); }); }); 

但是这不起作用,例如在register.js中 。 游泳池在那里没有定义…

 var pool = require('./database').pool; console.log(pool); 

这种常见的devise模式如何? 最好的马丁

为了理解为什么pool undefined您需要逐步查看代码。

1.在你的App.js你有这样的一行:

 var makePool = require('./myModule').createPool(options); 

其中将首先包含myModule ,然后调用结果的createPool

2.在你的myModuleindex.js中你有这样一行:

 var register = require('./lib/register') 

这行在module.exports被返回之前被调用,这是在.createPool(options)被调用之前调用的。

3.register.js你有这样的行:

  var pool = require('./database').pool; console.log(pool); 

但是当你尝试获取require('./database').pool它不存在,因为那时没有调用createPool

4.myModule完成所有事情之后, myModule createPool并创buildpool


那么你怎么解决这个问题?

一种方法是重构代码,以便对.pool的访问始终包含某些内容。 例如在调用require('./myModule')之前,在App.js调用require('./lib/database').createPool(options) require('./myModule')

但是,这不是最好的解决scheme,因为您需要写入您的文档,这个顺序是必需的,使您的代码工作。

更好的方法是使用某种asynchronous方法来请求池,而不是直接访问该属性。

要么使用callback:

 require('./lib/database') .getPool(function(err, pool) { //do something with the pool or show the error message }); 

或使用承诺(如蓝鸟 ):

 require('./lib/database').getPool() .then(function(pool) { //do something with the pool }) .catch(function(e) { //do something in case of the error }); 

您当然需要为您的getPool实现一些逻辑,这取决于用例,如果getPool没有pool ,那么直接继续出现错误,或者等到创build池之后,继续成功的状态。

答案很简单,池不是在register.js中创build的

 module.exports = { createPool: function(options) { console.log('creating Pool ...') return module.exports.pool = mysql.createPool(options); } } 

你需要先调用createPool,就像你在脚本中写的那样。