简体   繁体   English

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

[英]Loading multiple files synchronously in node.js

I am learning node.js and have build a micro-app around an MVC architecture. 我正在学习node.js,并围绕MVC架构构建了一个微型应用程序。

I have a router.js file which loads a controller based on the URI, which, in most cases, would load the views using the "fs" module. 我有一个router.js文件,该文件基于URI加载控制器,在大多数情况下,该文件将使用“ fs”模块加载视图。 The views being the HTML elements making up the web page (basically head, body, & footer) as 3 separate files . 视图是构成网页的HTML元素(基本上是头部,正文和页脚),为3个单独的文件

Here is the code for the 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;

As you can see the HTML elements are supposed to load in order (head.html, then the particular view for this controller - test.html, then footer.html). 如您所见,应该按顺序加载HTML元素(head.html,然后是该控制器的特定视图-test.html,然后是footer.html)。 But they sometimes do NOT. 但是他们有时不这样做。

They load in the "head, body, footer" order most of the time. 它们大部分时间按“头,身体,页脚”顺序加载。

Sometimes they load as "head, footer, body". 有时,它们以“头,页脚,身体”的形式加载。

Other times its "body, head, footer". 其他时候是“身体,头部,页脚”。

They never seem to load in any other configuration. 它们似乎从未加载任何其他配置。

Please see screenshots attached. 请参阅所附的屏幕截图。

头,身体,页脚

头,页脚,身体

身体,头部,页脚

Im am not sure what is happening here. 我不确定这里发生了什么。 Why are these files being loaded in any order but the one they are called?? 为什么这些文件以任何顺序加载,但它们被称为?

  • Please note I am intentially not using a framework like Express.js for learning purposes 请注意,我并不是出于学习目的而使用Express.js之类的框架

You cannot make assumptions about the ordering of responses for asynchronous requests. 您不能假设异步请求的响应顺序。 There are various factors that could affect this ordering (eg OS thread scheduling in the case of filesystem requests). 有多种因素可能影响此排序(例如,在文件系统请求的情况下,OS线程调度)。

So the solution to this is to either call them serially by nesting callbacks or chaining Promises or by using a module like async , or bind your callbacks to include relevant contextual information so you know which file just got loaded in your callback. 因此,解决方案是通过嵌套回调或链接Promises或使用诸如async类的模块来串行调用它们,或者将回调绑定为包含相关的上下文信息,以便您知道哪个文件刚刚加载到回调中。 An example of the latter might be something like: 后者的示例可能是这样的:

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

On a related note, you might look into using a templating system (that supports including partials (like headers and footers) and layouts) of some kind to avoid doing this kind of manual work. 在相关说明中,您可能会考虑使用某种模板系统(该模板系统支持包括部分内容(如页眉和页脚)和布局),以避免进行此类手动工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM