在Node.js中异步读取和缓存多个文件

5

我有一个数组,保存了多个文件的URL。例如:

var files = ['1.html', '2.html', '3.html'];

我需要异步读取它们并将它们保存在一个名为cache(cache = {})的对象中。为此,我使用了以下代码:
for(var i = 0; i < files.length; i++){
    require('fs').readFile(files[i], 'utf8', function (error,data) {
        cache[files[i]]=data;
    });
}

最终我得到了结果:
cache = { undefined : 'File 3 content' }

我理解 "readFile" 在循环结束后才执行,因此失去了作用域。有没有一种方法可以解决这个问题或者另外一种从数组中读取文件并缓存它们的方法?

2个回答

19

当你的回调函数执行 readFile 时,for循环已经完成。所以 i 将会是 files.lengthfiles[i] 将会是 undefined。为了缓解这个问题,你需要将变量封装在闭包中。最简单的方法是创建一个函数来执行你的 readFile 调用,并在循环中调用该函数:

function read(file) {
    require('fs').readFile(file, 'utf8', function (error,data) {
        cache[file]=data;
    });
}

for(var i = 0; i < files.length; i++){
    read(files[i]);
}

为了更好地控制执行,您可能需要查看async

function readAsync(file, callback) {
    fs.readFile(file, 'utf8', callback);
}

async.map(files, readAsync, function(err, results) {
    // results = ['file 1 content', 'file 2 content', ...]
});

编辑:使用了异步示例的辅助函数。


我正在使用异步,但我需要将'utf8'作为参数传递给readFile函数,我该怎么做? - jeroen
1
@jeroen:你需要创建一个帮助函数,它传递'utf8'。类似这样:function read(file, callback) { fs.readFile(file, 'utf8', callback) }编辑:请查看编辑后的帖子! - Linus Thiel

0

现有的答案对我没有用。我找到了一个可以胜任的NPM包:https://www.npmjs.com/package/read-multiple-files。在命令行中运行npm install read-multiple-files后,这是我使用的代码:

var files = ['1.html', '2.html', '3.html'];

console.log("\n");

readMultipleFiles(files, 'utf8', function(err, inputFiles) {
  if(err) {
    console.log("Read Error: " + err);
  }

  fileOne = inputFiles[0];
  fileTwo = inputFiles[1];
  ...

  console.log(fileOne);
  console.log(fileTwo);

});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接