【发布时间】:2015-07-12 11:13:23
【问题描述】:
在我的routes.js 文件中,我有这个:
var pages = require('./pages')();
...
app.get('/:page', function(req, res, next) {
var p = req.params.page;
if (p in pages) {
res.render('page', pages[p]);
} else {
next();
}
});
pages.js:
module.exports = function() {
var fs = require('fs'),
ret = [],
dir = './pages',
files = fs.readdirSync(dir);
files.forEach(function(file) {
var text = fs.readFileSync(dir + '/' + file, 'utf-8'),
fileName = file.substr(0, file.lastIndexOf('.'));
ret[fileName] = {content: text};
});
return ret;
};
当我运行 node.js 时,此代码只运行一个。这就是我可以使它异步的方法:
require('./pages')(function(pages) {
app.get('/:page', function(req, res, next) {
var p = req.params.page;
if (p in pages) {
res.render('page', pages[p]);
} else {
next();
}
});
});
pages.js:
module.exports = function(callback) {
var fs = require('fs'),
ret = [],
dir = './pages';
fs.readdir(dir, function(err, files) {
if (err) throw err;
files.forEach(function(file, i) {
fs.readFile(dir + '/' + file, 'utf-8', function(err, text) {
if (err) throw err;
var fileName = file.substr(0, file.lastIndexOf('.'));
ret[fileName] = {content: text};
if ( i === (files.length - 1) ) callback(ret);
});
});
});
};
假设总页面大小不超过 1 MB,我可以无限期地将文本缓存到内存中,而不会因内存不足而导致节点崩溃。
-
我应该使用异步代码吗?
根据我了解到的情况,异步版本将使节点更快地开始监听本地主机,但
/:pageURL 仅在文件加载到内存时才有效。 -
异步代码的模式是否正确?
-
如果我需要在另一个文件中重用
pages对象怎么办?目前只能通过routes.js访问。
我可以像这样重写pages.js 只执行一次吗:
var ret = [];
module.exports = function(callback) {
var fs = require('fs'),
dir = './pages';
if (ret.length < 1) {
fs.readdir(dir, function(err, files) {
if (err) throw err;
files.forEach(function(file) {
fs.readFile(dir + '/' + file, 'utf-8', function(err, text) {
if (err) throw err;
var fileName = file.substr(0, file.lastIndexOf('.'));
ret[fileName] = {content: text};
if ( i === (files.length - 1) ) callback(ret);
});
});
});
} else {
callback(ret);
}
};
- 如果
require('./pages')(function(pages) {})被多次调用会怎样?if条件是否有可能失败?我无法解决这个问题。
【问题讨论】:
-
是的,同步加载 (require) 是 node.js 的做法,而且人们似乎仍在使用 node.js... 使用 async 并没有很大的回报加载,因为在满足依赖关系之前应用程序将无法使用。一旦你开始,同步可能会减慢一堆请求,但在所有内容加载之前什么都不会发生,所以使用同步保持快速和简单。
-
还考虑到您是从 HDD 加载,而不是 HTTP,因此异步并不像在浏览器中那样重要,因为同步 ajax 会冻结选项卡并可能需要一段时间......
标签: javascript node.js asynchronous express promise