例如,我有 app.js
来加载一个模块对象:M
加载(require
)一个文件:_core.js
,然后M
的属性是通过在目录下加载(require
)文件来添加的:./Project_Functions/
var Project_FunctionsDIR = './Project_Functions/';
var Project_coreFile = '_core.js';
var M = require(Project_FunctionsDIR + Project_coreFile);
require("fs")
.readdir(Project_FunctionsDIR,
function(err, files)
{
files.forEach(function(file)
{
if (file !== Project_coreFile)
{
var name = file.split('.js')[0];
var filepath = Project_FunctionsDIR + file;
M[name] = require(filepath);
}
});
});
console.log('module.exports');
module.exports = M;
此处,构造的moduleObject:M
由module.exports
导出。
请注意fs.readdir
是异步的,因此在module.exports = M;
中构建 M
属性之前,{em}评估app.js
。
现在,我想在 M
中测试此对象test.js
,
var expect = require('chai').expect;
var M = require('./app.js');
//........
在var M = require('./app.js');
行,评估app.js
,表示在构建整个属性之前导出M
对象
事实上,我在setTimeout
回调中插入了fs.readdir
,显然测试失败,M
对象尚未就绪。
首先,我认为module.exports = M;
应放在fs.readdir
回调中,但如果我这样做,现在var M = require(Project_FunctionsDIR + Project_coreFile);
部分失败,可能是因为module.exports = M;
没有暴露正确阅读。
是的,这可以通过使用fs.readdirSync
来解决,实际上,当我遇到这类问题时我一直在这样做,但是,我总是觉得使用节点同步方法感到不舒服,而是试图寻找一个更智能的解决方法。
所以,这是我的问题;可以通过不使用Sync方法来解决这个问题吗?还是不可能?
此外,我想更多地询问一下。
我们可以在不使用Sync方法的情况下执行任何操作,或者在某些情况下,我们必须使用node.js
中的同步方法吗?
在函数式编程方案中,如果可能,应避免使用Sync方法,因为Sync概念取决于非函数(回调)但时间。
谢谢你的想法。
编辑:
我刚刚在这里找到了一个相关主题: Asynchronous initialization of Node.js module
结论是我们必须使用Sync方法来对应Sync方法。在这种情况下,require
是同步方法。
答案 0 :(得分:0)
node.js使用CommonJS模块模式,根据定义,在加载时同步导出其公开的对象。您尝试做的事情不可能是异步的,尽管您可以通过将其他文件公开到“主”导出中来实现。如果要从一个对象动态公开目录中的所有文件,只需使用同步readdir,它只会在启动时执行。
答案 1 :(得分:0)
一种常见模式是模块公开异步initialize
方法,该方法执行异步工作。对于您的模块,它看起来像这样:
var Project_FunctionsDIR = './Project_Functions/';
var Project_coreFile = '_core.js';
var M = require(Project_FunctionsDIR + Project_coreFile);
M.initialize = function(next) {
require("fs")
.readdir(Project_FunctionsDIR,
function(err, files)
{
files.forEach(function(file)
{
if (file !== Project_coreFile)
{
var name = file.split('.js')[0];
var filepath = Project_FunctionsDIR + file;
M[name] = require(filepath);
}
});
next();
});
}
module.exports = M;
然后你可以用:
进行测试var M = require('./app.js');
M.initialize(function() {
//........
}
这是一个有用的模式,因为许多异步方法没有同步版本,它允许您并行运行许多这些异步initialize
,大大减少了较大应用程序的启动时间。