2012-04-30 5 views
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); 
      }); 
     }); 
}); } 

問題がasyncronousされ、私は機能の複数のインスタンスが同時にファイルに書いている時間があることを感知し、ということです。このフラックスを制御して書き込みタスクをキューイングできる方法はありますか?

このコードの目的は、ディレクトリにある.cssファイルをマージすることです。このプロジェクトでは外部ツールを使用できません。

EDIT ANSWER:この目的のために、私はマージしたいすべての.cssファイルのパスを収集し、それらをすべて持ってからシンクロナス関数を呼び出して書き込みます。

VAR結果= []

がそこにあるものです。私はそれを実現しました。

+0

の例では、ディレクトリ内のすべてのファイルのcommon.cssでハローをopenningと足すいます3つのファイルがある場合は、 "hellohellohello"と書きます。これはあなたの本当のコードですか?この目的のためには、ファイルの数を取得してから、「hello」をN回だけ開いて書き込むことができます。 –

答えて

0

まあ、私は同じ目的のためにシリアル再帰関数を使用して終了しました。それは問題を解決しました。ユーザーの答えに「chjj」node.js fs.readdir recursive directory search

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(); 
     } 
     }); 
    })(); 
    }); 
}; 

から撮影でご提案ありがとうございました:)

0

私はあなたがスタンドアロンアプリケーションとしてこれをやっているなら、もっと大きなアプリケーションの一部ではなく、すべてのcssファイルをconsole.logに書き込んで、 "node combine.js> combined.cc" "私がFileStreamsとconsole.logを使って見たことから、それは書き込みを誤解させません。

+0

さて、この目的のために、私はマージしたいすべての.cssファイルのパスを集めることができます。そして、それらをすべて手に入れた後に、シンクロナス関数を呼び出すと-.-とにかくあなたの答えに感謝しますuser1291492!これがうまくいけない場合は、私はあなたの提案に表示されます:) かなり大きなWebアプリケーションです。 –

+0

すべての関数呼び出しがいつ終了したかを正確に知るための提案はありますか?最後のファイルが見つかった時点を正確に把握する。 –

+0

すべてのディレクトリの検索が終了するまで、最後のファイルが見つかったかどうかはわかりません。すべてのディレクトリを検索したことがどのように分かりますか?ノードのコールバックフレームワークでこれを知るのは難しい – ControlAltDel

1

私は必ず物事はasync.forEachSeries(arr, eachFn, doneFn)

0

含めて、正しい順序で起こるあなたが最初にcommon.cssを開き、開いているファイルディスクリプタを保つことができる作るための能力を持っているasync.jsライブラリのようなものを使用してに見えるだろうと考えて、 CSSファイルが見つかるたびにfs.write(id, ...)に電話してください。これは毎回common.cssを再開する現在の方法の代わりです。

コードには、helloをファイルに書き込んでいるようです。それが文字通り真実であるか、またはあなたが書いているものが比較的短い場合(通常はプラットフォームによっては512または4096バイト)、common.cssへのすべてのアペンドはアトミックなので、同時に書いた異なる非同期関数はそれぞれを妨げませんその他。

+0

私はあなたの提案を試みましたが、common.cssが正しく書かれていません。私はこれを行うために同期ループを作成することができたので、複数のインスタンスが同時に書き込まれるという問題はありません。これはおそらく追加機能に関するものです。私はうまく働いてはいけません。私はそれがfs.write()を参照してください。 node.jsの関数はバッファであり、文字列ではありません。私はそれを試みます。 –

関連する問題