Reading and returning multiple files in Node.js using fs.readFile

The primary issue with what you have is that response.end() gets called right away. You need to only call it after the files have done their response.write calls.

The easiest way would be to use a control flow library. Managing multiple asynchronous callbacks is generally complicated.

https://github.com/joyent/node/wiki/modules#wiki-async-flow

I’m going to use the async library because it’s the one I know best.

var fs = require('fs');
var async = require('async');

function css(response) {
  response.writeHead(200, {"Content-Type": "text/css"});

  async.eachSeries(
    // Pass items to iterate over
    ['css/bootstrap.css', 'css/bootstrap-responsive.css'],
    // Pass iterator function that is called for each item
    function(filename, cb) {
      fs.readFile(filename, function(err, content) {
        if (!err) {
          response.write(content);
        }

        // Calling cb makes it go to the next item.
        cb(err);
      });
    },
    // Final callback after each item has been iterated over.
    function(err) {
      response.end()
    }
  );
}

If you want to accomplish this without a library, or just want another way, this is how I would do it more directly. Basically you keep a count and call end once both file reads have finished.

function css(response) {
  response.writeHead(200, {"Content-Type": "text/css"});

  var count = 0;
  var handler = function(error, content){
    count++;
    if (error){
      console.log(error);
    }
    else{
      response.write(content);
    }

    if (count == 2) {
      response.end();
    }
  }

  fs.readFile('css/bootstrap.css', handler);
  fs.readFile('css/bootstrap-responsive.css', handler);
}

Leave a Comment