Javascript 在启动时使用同步代码将数据加载到内存中可以吗?
在我的Javascript 在启动时使用同步代码将数据加载到内存中可以吗?,javascript,node.js,asynchronous,express,promise,Javascript,Node.js,Asynchronous,Express,Promise,在我的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.e
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;
};
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);
});
});
});
};
当我运行node时,这段代码只运行一个。这就是我如何使其异步的方法:
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() {
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;
};
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);
});
});
});
};
假设总页面大小不会超过1MB,我可以无限期地将文本缓存到内存中,而不会因为内存不足而导致节点崩溃
/:page
url仅在文件加载到内存中时才起作用
页面
对象,该怎么办?现在它只能在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);
}
};
var ret=[];
module.exports=函数(回调){
var fs=require('fs'),
目录='/页';
如果(返回长度<1){
fs.readdir(dir,函数(err,文件){
如果(错误)抛出错误;
forEach(函数(文件){
fs.readFile(dir+'/'+文件'utf-8',函数(err,text){
如果(错误)抛出错误;
var fileName=file.substr(0,file.lastIndexOf('.');
ret[fileName]={content:text};
if(i==(files.length-1))回调(ret);
});
});
});
}否则{
回调(ret);
}
};
require('./pages')(函数(pages){})
,该怎么办?如果条件失败,是否有可能出现?我想不起这件事回调。多次调用app.get('/:page',…)
不是您想要的
如果我需要在另一个文件中重用pages对象,该怎么办?目前,它只能在routes.js中访问
您可以将它从routes.js
传递到其他模块。或者只需重写pages.js
以静态方式存储它,并只执行一次异步操作,这样您就可以多次需要它
如果一起多次调用require('./pages')(函数(pages){})
,该怎么办?如果条件失败,是否有可能发生这种情况
是的,它肯定会失败,因为您只异步填充ret
我想不起这件事
使用承诺。这个函数可以作为异步的、不可变的值,这正是您需要的。它们将保证回调只调用一次,每个回调都使用相同的ret
值调用,并提供更多有用的功能(比如为您管理并行文件读取)
您需要从
pages.js
导出承诺是的,同步加载(require)是node.js的工作方式,而且人们似乎仍然在使用node.js。。。使用async加载不会带来巨大的回报,因为在满足依赖关系之前,应用程序将无法使用。一旦你走了,同步可以减慢一批请求,但是直到所有的东西被加载为止,没有任何事情发生,所以使用Syc保持快速和简单。也考虑你是从HDD加载的,而不是HTTP。因此,在浏览器中,异步并不像在浏览器中那么重要,在浏览器中,syncajax将冻结选项卡,并且可能需要一段时间……非常感谢您的回答。我完全忽略了异步代码中的回调在循环中这一事实。因此,我可以添加一个if条件,以确保回调仅在循环的最后一次迭代中调用,这也会修复异步代码,对吗?是的,但它非常复杂,并且仍然存在多次调用的问题。只需使用同步代码或承诺。非常感谢,非常感谢您的帮助。我的理解是if(i==(files.length-1))回调(ret)
将完成这项工作(不计算多次调用问题),但readFile
是异步的,因此可以在调用其他回调之前执行最后一次回调。是的,您不能使用闭包中的i
变量,您必须使用每次调用时增加的计数器。但实际上,您不想手动执行此操作,可以使用承诺(Promise.all
)或类似async.js(async.parallel
)的助手库。