1

我在使用 node.js 时遇到了一些问题。我要做的是在“./”+req.user.email 中获取一个目录数组,然后遍历它们,找出它们的大小并在输出中添加一个表格行,正如您在代码中看到的那样。最后,我不想使用 res.send() 发送所有表行。

但是我得到的唯一输出是:

<tr></tr>

对于数组中的每个文件。似乎 forEach 函数根本不等待 readSizeRecursive 。readSizeRecursive 函数是异步的,我相信这是导致问题的原因,但我不知道如何解决这个问题。

任何帮助将不胜感激,我也包含了 readSizeRecursive 函数。谢谢!

  var output = "";
  fs.readdir("./" + req.user.email, function (err, files) {
    files.forEach(function(file){
      output += "<tr>";
      readSizeRecursive("./"+req.user.email+"/"+file, function (err, total){
        output += '<td>' + file + '</td><td>' + total + '</td>';
      });
      output += "</tr>"
    });
    res.send(output)
  });

读取大小递归():

// Function to find the size of a directory
function readSizeRecursive(item, cb) {
  fs.lstat(item, function(err, stats) {
    var total = stats.size;

    if (!err && stats.isDirectory()) {
      fs.readdir(item, function(err, list) {
        async.forEach(
          list,
          function(diritem, callback) {
            readSizeRecursive(path.join(item, diritem), function(err, size) {
              total += size;
              callback(err);
            }); 
          },  
          function(err) {
            cb(err, total);
          }   
        );  
      }); 
    }   
    else {
      cb(err, total);
    }   
  }); 
}
4

2 回答 2

0

请为这种模式使用异步模块。Usingasync.each将允许您异步计算每个文件夹的大小,然后在您完成单独计算所有内容后返回大小。

var output = [];

fs.readdir('./' + req.user.email, function (err, files) {
  async.each(compute, report);
});

function compute (file, done) {
  // calculate size, then callback to signal completion
  // produce a result like below, then invoke done()
  var obj = { files: [
    { name: file, size: size },
    { name: file, size: size },
    { name: file, size: size }
  ]};
  output.push(obj);
  done();
}

// doesn't need to be this awful
function format (list) {
  var result = [];

  list.forEach(function (item) {
    var description = item.files.map(function (file) {
      return util.format('<td>%s</td><td>%s</td>', file.name, file.size);
    });
    result.push(description);
  });

  result.unshift('<tr>');
  result.push('</tr>');
  return result.join('</tr><tr>');
}

function report (err) {
  if (err) { return next(err); }

  var result = format(output);
  res.send(result);
}

例如,通过这种方式,您可以轻松地交换不同的功能,在不改变文件大小树计算的情况下更改格式。

您的主要问题是控制流。res.send当您异步循环并计算大小时,您返回。

于 2013-10-28T17:15:04.203 回答
-1
var fs = require ("fs");

var createTableContent = function (p, cb){
    var read = function (p, cb){
        //Prevent recursion if error
        if (err) return cb ();

        fs.stat (p, function (error, stats){
            if (error){
                err = error;
                return cb ();
            }

            if (stats.isDirectory ()){
                var dirSize = 0;

                fs.readdir (p, function (error, entries){
                    if (error){
                        err = error;
                        return cb ();
                    }

                    var pending = entries.length;
                    //Empty dir
                    if (!pending) return cb (0);

                    entries.forEach (function (entry){
                        read (p + "/" + entry, function (entrySize){
                            dirSize += entrySize;
                            if (!--pending) return cb (dirSize);
                        });
                    });
                });
            }else{
                cb (stats.size);
            }
        });
    };

    //A lot of errors can be produced, return only the first one
    var err = null;

    //Suppose p is a dir
    fs.readdir (p, function (error, entries){
        if (error) return cb (error);

        var content = "";
        var pending = entries.length;
        if (!pending) return cb (null, content);

        entries.forEach (function (entry){
            read (p + "/" + entry, function (totalSize){
                if (err) return cb (err);
                content += "<tr><td>" + entry + "</td><td>" + totalSize + "</td></tr>";
                if (!--pending){
                    //End
                    cb (null, content);
                }
            });
        });
    });
};

//Here goes the "email" path
createTableContent (".", function (error, content){
    if (error) return console.error (error);

    console.log (content);
});
于 2013-10-28T20:38:43.380 回答