一尘不染

使用fs.readFile在Node.js中读取和返回多个文件

node.js

我正在编写一个简单的请求处理程序以返回一对CSS文件。使用fs.readFileSync,这很容易。但是,我很难使用异步版本的readFile完成相同的任务。下面是我的代码。将我的response.write()方法调用拆分到两个不同的回调中似乎是有问题的。有人可以指出我做错了什么吗?有趣的是,如果我将response.end()放在第一个else语句中,则此代码有效。但是,这产生了一个问题,即第二个css文件没有返回(因为response.end()已被触发)。

function css(response) {

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

  fs.readFile('css/bootstrap.css', function(error, content){
    if(error){
      console.log(error);
    }
    else{
      response.write(content);
    }
  });
  fs.readFile('css/bootstrap-responsive.css', function(error, content){
    if(error){
      console.log(error);
    }
    else{
      response.write(content)
    }
  });
  response.end();
}

阅读 450

收藏
2020-07-07

共1个答案

一尘不染

您所拥有的主要问题是立即response.end()被致电。您只需在文件完成response.write调用后调用它。

最简单的方法是使用控制流库。管理多个异步回调通常很复杂。

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

我将使用异步库,因为它是我最了解的一个。

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

如果您想在没有库的情况下完成此工作,或者只是想用另一种方式,这就是我将更直接地做到这一点的方式。基本上,您保留a
countend在两个文件读取完成后调用。

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);
}
2020-07-07