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

时间:2016-09-09 22:01:23

标签: javascript jquery html css node.js

我正在学习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;。

它们似乎永远不会加载任何其他配置。

请参阅附件截图。

head, body, footer

head, footer, body

body, head, footer

我不确定这里发生了什么。为什么这些文件按任何顺序加载,但它们被称为??

  • 请注意我一直没有使用像Express.js这样的框架用于学习目的

1 个答案:

答案 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();
    }
  }
}

在相关的说明中,您可能会考虑使用模板系统(支持包含某种类型的部分(如页眉和页脚)和布局)以避免进行此类手动工作。