2

我正在使用这个异步递归函数来遍历目录的文件和文件夹,当找到一个 .css 文件时,我将数据附加到一个名为“common.css”的文件中。

var walk = function(dir, done) {
 var results = [];

 fs.readdir(dir, function(err, list) {
      if (err) return done(err);
      var pending = list.length;
      if (!pending) return done(null);
      list.forEach(function(file) {
           file = dir + '/' + file;
           fs.stat(file, function(err, stat) {
                if (stat && stat.isDirectory()) {
                     minimizer(file, function(err, res) {
                          results = results.concat(res);
                          if (!--pending) done(null);
                     });
                } else if(file) {
                     fs.open('common.css', 'a', 666, function( err, id ) {
                         fs.write( id, 'hello', null, 'utf8', function(){
                             fs.close(id, function(){
                                  console.log('file closed');
                             });
                         });
                     });
                }
                if (!--pending) done(null);
           });  
      });
});   }

问题是,由于是异步的,我感觉到有时函数的多个实例同时写入文件。有什么办法可以控制这种通量并将写入任务排队?

此代码的目的是合并在目录中找到的 .css 文件。我不能在这个项目中使用外部工具。

编辑答案:嗯,为此,我可以收集我想要合并的所有 .css 文件的路径,在我拥有它们之后,调用一个同步函数来编写它们。

这就是

变量结果 = []

是为了。我才意识到。

4

4 回答 4

1

我认为我会考虑使用async.js库之类的东西,它具有确保事情以正确的顺序发生的能力,包括async.forEachSeries(arr, eachFn, doneFn)

于 2012-04-30T15:30:21.027 回答
0

我的建议是,如果您将其作为独立应用程序执行 - 不是某些更大应用程序的一部分,您可以将所有 css 文件写入 console.log 并通过“node combine.js > combine.cc”调用。从我使用 FileStreams 和 console.log 看到的情况来看,它不会乱写。

于 2012-04-30T15:10:04.027 回答
0

您可以common.css在开始时打开并保持文件描述符打开,然后fs.write(id, ...)在遇到 CSS 文件时调用。这不是您当前common.css每次重新打开的方法。

在您的代码中,看起来您正在写入hello文件。如果确实如此,或者如果您编写的内容相对较短(通常为 512 或 4096 字节,具体取决于平台),则所有附加都common.css将是原子的,因此同时写入的不同异步函数不会相互干扰.

于 2012-04-30T19:23:19.783 回答
0

好吧,我最终出于同样的目的使用了串行递归函数。它解决了这个问题。在从node.js fs.readdir 递归目录搜索中获取的用户“chjj”的答案中

var fs = require('fs');
var walk = function(dir, done) {
  var results = [];
  fs.readdir(dir, function(err, list) {
    if (err) return done(err);
    var i = 0;
    (function next() {
      var file = list[i++];
      if (!file) return done(null, results);
      file = dir + '/' + file;
      fs.stat(file, function(err, stat) {
        if (stat && stat.isDirectory()) {
          walk(file, function(err, res) {
            results = results.concat(res);
            next();
          });
        } else {
          results.push(file);
          next();
        }
      });
    })();
  });
};

谢谢大家的建议 :)

于 2012-05-10T09:42:28.300 回答