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ファイルのパスを収集し、それらをすべて取得したら、同期関数を呼び出してそれらを書き込みます。

それが

var results = []

のためにあります。気づいた。

4

4 に答える 4

1

物事が正しい順序で確実に行われるようにする機能を備えたasync.jsライブラリのようなものを使用することを検討すると思います。async.forEachSeries(arr, eachFn, doneFn)

于 2012-04-30T15:30:21.027 に答える
0

私の提案は、これをスタンドアロンアプリケーションとして実行している場合です。これは、はるかに大きなアプリの一部ではなく、すべてのcssファイルをconsole.logに書き込み、「nodecombine.js>combined.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 に答える