异步读取文件

时间:2016-06-17 06:45:03

标签: javascript node.js

我正在尝试读取一些文件并将其名称存储在nodejs中的数组中。我做了一个功能。它读取文件,并在控制台中打印出来,但数组的输出是[]。我假设这是因为node.js是异步的,但我认为回调会修复它?

readCurdir("./uploads/", curDirReadFinn); 
function readCurdir(dir, callback){
  var tmpArray = []; 
  fs.readdir(dir, function(err, files){
    if(err){
      if(err.code==='EISDIR'){}
      else{
        console.log(err);
      }
      return; 
    }
    files.forEach(function(file){
      fs.readFile(dir + file, 'utf-8', function(err, data){
        if(err){
          if(err.code==='EISDIR'){}
          else{
            console.log(err);
          }
          return; 
        }
        tmpArray.push(file); 
        console.log(file);   //this prints
      }); 
    }); 
  }); 
  callback(tmpArray); 
} 
function curDirReadFinn(array){ 
    console.log(array); //Output: []
}

我也试过这个:

files.forEach(function(file){
  fs.readFile(dir + file, 'utf-8', function(err, data){
    if(err){
      if(err.code==='EISDIR'){}
      else{
        console.log(err);
      }
      return; 
    }
    tmpArray.push(file); 
    counter++; 
    if(counter === files.lenght){
    callback(tmpArray); 
    }
  }); 
});

2 个答案:

答案 0 :(得分:2)

你第二次尝试时得到了正确的想法。 在我简化它之后,它会完美运行:

function readCurdir(dir, callback){
  var tmpArray = []; 

  fs.readdir(dir, function(err, files) {
    if (err) {
      return console.log(err);
    }

    var counter = files.length;

    files.forEach(function(file) {
      fs.stat(path.join(dir, file), function(err, stats) {
        if (err) {
          console.log(err);
        }
        else if (stats.isFile()) {
          tmpArray.push(file); 
        }

        --counter === 0 && callback(tmpArray);
      }); 
    });
  }); 
} 

您可以使用async模块进一步简化(并更容易传播错误):

async.each(files, function(file, cb) {
  fs.stat(path.join(dir, file), function(err, stats) {
    if (err) {
      return cb(err);
    }
    else if (stats.isFile()) {
      tmpArray.push(file); 
    }

    cb();
  }); 
}, function(err) {
    callback(err, tmpArray)
});

答案 1 :(得分:1)

异步代码再次出现! fs.readdir()是异步的。您的callback方法与fs.readdir()的执行分开调用。这就是当您在回调方法tmpArray中记录curDirReadFinn()时,stat为空的原因。

有一些方法可以解决您的问题:

  1. 同步准备好您的目录和文件。 NodeJS有方法。见这里:https://nodejs.org/api/fs.html#fs_fs_readdirsync_path_options

  2. 正如@Thomas所提到的,您可以利用isFile()int mySpecificID = 3; List<MyObject> list; for(MyObject myobject : list) { if(myobject.getId()==mySpecificID) { //We found it MyObject objectFound = myobject; } } 来更快地完成它。通常不需要繁重的异步代码。

  3. 使用Promises!