我正在学习node.js,并围绕MVC架构构建了一个微应用程序。
我有一个router.js文件,它根据URI加载一个控制器,在大多数情况下,它会使用" fs"加载视图。模块。构成网页的HTML元素(基本上是头部,正文和页脚)的视图为 3个单独的文件。
以下是控制器的代码:
var load_view = 'test.html';
function data(response, request, fs){
response.writeHead(200, {"Content-Type": "text/html"});
var count = 0;
var handler = function(error, content){
count++;
if(error) console.log(error);
else response.write(content);
if(count==3) response.end();
}
fs.readFile('view/elements/head.html', handler); // should load 1st
fs.readFile('view/'+load_view, handler); // should load 2nd
fs.readFile('view/elements/footer.html', handler);// should load 3rd
}
exports.data = data;
正如您所看到的,HTML元素应按顺序加载(head.html,然后是此控制器的特定视图 - test.html,然后是footer.html)。但他们有时不这样做。
他们加载在头部,身体,脚部和#34;大部分时间都是订购。
有时候他们会按照头部,页脚,身体等方式加载。
其他时候它的身体,头部,页脚和#34;。
它们似乎永远不会加载任何其他配置。
请参阅附件截图。
我不确定这里发生了什么。为什么这些文件按任何顺序加载,但它们被称为??
答案 0 :(得分:0)
您不能对异步请求的响应顺序做出假设。有多种因素可能影响这种排序(例如,在文件系统请求的情况下,OS线程调度)。
所以解决这个问题的方法是通过嵌套回调或链接Promise或使用类似async
的模块来串行调用它们,或者绑定你的回调以包含相关的上下文信息,这样你就知道刚加载了哪个文件你的回调。后者的一个例子可能是:
function data(res, req, fs) {
// Files to be loaded, in the order to be written to the response
var files = [
'view/elements/head.html',
'view/' + load_view,
'view/elements/footer.html'
];
// Start read requests, each with a callback that has an extra
// argument bound to it so it will be unshifted onto the callback's
// parameter list
for (var i = 0; i < files.length; ++i)
fs.readFile(files[i], handler.bind(null, i));
var count = 0;
function handler(index, err, content) {
// Make sure we don't send more than one response on error
if (count < 0)
return;
if (err) {
count = -1;
console.log('Error for file: ' + files[index]);
console.log(err);
res.writeHead(500);
return res.end();
}
// Reuse our `files` array by simply replacing filenames with
// their respective content
files[index] = content;
// Check if we've read all the files and write them in order if
// we are finished
if (++count === files.length) {
res.writeHead(200, { 'Content-Type': 'text/html' });
for (var i = 0; i < files.length; ++i)
res.write(files[i]);
res.end();
}
}
}
在相关的说明中,您可能会考虑使用模板系统(支持包含某种类型的部分(如页眉和页脚)和布局)以避免进行此类手动工作。