javascript - 在node.js中同步加载多个文件

标签 javascript jquery html css node.js

我正在学习 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)。但他们有时不会。

它们大部分时间以“头部、主体、页脚”顺序加载。

有时它们加载为“页眉、页脚、正文”。

其他时候是“主体、头部、页脚”。

它们似乎从不加载任何其他配置。

请参阅随附的屏幕截图。

head, body, footer

head, footer, body

body, head, footer

我不确定这里发生了什么。为什么这些文件以任何顺序加载,而不是它们被调用的顺序?

  • 请注意,我有意不使用像 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/

相关文章:

javascript - 如何让一个 CSS 类一次只为一个对象工作?

html - 在图像旁边显示两行文本

javascript - 返回不一致结果的日期(取决于是否存在前导零)

php - 使用 javascript/jquery 动态操作 php cookie

jquery - 使用 jquery 和 typescript

html - 我的视差页面右侧出现神秘的空白

javascript - jQuery iframe 滚动事件 (IE)

javascript - 如何在 node.js 中读取整个文本流?

javascript - 有谁知道一个好的免费网络应用程序批量上传工具?

javascript - 无法使用 Geolocations API 在 JS Codepen 中的函数之间传递 var