我正在学习 node.js 并围绕 MVC 架构构建了一个微型应用程序。
我有一个 router.js 文件,它根据 URI 加载 Controller ,在大多数情况下,它会使用“fs”模块加载 View 。 View 是构成网页的 HTML 元素(主要是页眉、正文和页脚),作为 3 个单独的文件。
Controller 代码如下:
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,然后是该 Controller 的特定 View - test.html,然后是 footer.html)。但他们有时不会。
它们大部分时间以“头部、主体、页脚”顺序加载。
有时它们加载为“页眉、页脚、正文”。
其他时候是“主体、头部、页脚”。
它们似乎从不加载任何其他配置。
请参阅随附的屏幕截图。
我不确定这里发生了什么。为什么这些文件以任何顺序加载,而不是它们被调用的顺序?
- 请注意,我有意不使用像 Express.js 这样的框架来进行学习
最佳答案
您不能假设异步请求的响应顺序。有多种因素可能会影响此顺序(例如,在文件系统请求的情况下操作系统线程调度)。
因此,解决方案是通过嵌套回调或链接 Promises 或使用类似 async
的模块连续调用它们,或者绑定(bind)回调以包含相关的上下文信息,以便您知道哪个文件只是已加载到您的回调中。后者的一个例子可能是这样的:
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();
}
}
}
在相关说明中,您可能会考虑使用某种模板系统(支持包括部分内容(如页眉和页脚)和布局)来避免进行此类手动工作。
关于javascript - 在node.js中同步加载多个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39420306/