2016-09-28 37 views
0

私が行っているプロジェクトでは、ファイルとその内容に基づいてツリーモデルを構築する関数があります。私の解析ファイル関数は再帰的であり、ディレクトリツリー内で深く進むことができない/それ以上のファイルを含んでいないファイルをヒットしなくなるまで、自己呼び出しを続けます。しかし、再帰的なので、私はこの関数のコールバックを設定する方法を知らない。現時点では、私は自分のコンストラクトツリーメソッドをタイムアウトしていますが、これは私の問題に対する恐ろしい信頼できない解決策です。ここに私のコードです:回帰的再帰的メソッドのコールバック?

function constructTree(dir){ 
    tree = new TreeModel() 
    root = tree.parse({name: 'Marshall McGee Sample Pack'}); 
    parseFiles(dir, root, tree); 
    setTimeout(function(){ 
    root.all().forEach(function(node){ 
     console.log(node.model.name); 
    }); 
    }, 1000) 
} 

function parseFiles(dir, parrent, tree){ 
    fs.readdir(dir, function(err, files){ 
    if(files){ 
     for(i = 0; i < files.length; i++){ 
      parrent.addChild(tree.parse({name: files[i]})); 
      console.log(files[i]); 
      parseFiles(dir + "/" + files[i], parrent, tree); 
     } 
    } 
    }); 
} 

このコードは "ひどく恐ろしく"です。ディレクトリ全体を検索したかどうか、またはこれを正しく行う方法を決定する方法はわかりません。私はこれをうまく説明してくれればと思う!ありがとうございました、そして、どんなヘルプもappricatedです!

+0

コールバック関数とはどういう意味ですか? – prabodhprakash

+0

私は 'javascript'タグを追加しました。なぜなら、これまでに何の答えも得られなかった理由が不足しているからです。 – trincot

答えて

1

parseFiles関数にコールバック引数を追加し、そのコールバックが(非同期的に)ジョブを完了したときにコールバックさせる必要があります。

特定のフォルダ内のすべてのアイテムがトラバースされたことを知るには、カウントを保持し、最後のものが完了したときにのみ(コールバックを介して)ツリーは(count変数を参照してください)完了:発信者はコールバックを渡す義務はない

function constructTree(dir){ 
    var tree = new TreeModel() 
    var root = tree.parse({name: 'Marshall McGee Sample Pack'}); 
    // instead of timer, pass a callback function that should be called 
    // when the whole tree has been loaded. 
    parseFiles(dir, root, tree, function() { 
    root.all().forEach(function(node){ 
     console.log(node.model.name); 
    }); 
    }); 
} 

function parseFiles(dir, parrent, tree, done){ 
    fs.readdir(dir, function(err, files){ 
    // Only proceed here when there is at least one file (added condition) 
    if(files && files.length){ 
     // keep track how many items still need to be collected: 
     var count = files.length; 
     for(var i = 0; i < files.length; i++){ 
     parrent.addChild(tree.parse({name: files[i]})); 
     console.log(files[i]); 
     parseFiles(dir + "/" + files[i], parrent, tree, function() { 
      count--; 
      // if we have all items (recursively) added to the tree, notify the caller 
      if (!count && done) done(); 
     }); 
     } 
    } else { 
     // If no information in this folder, notify caller immediately 
     if (done) done(); 
    } 
    }); 
} 

として、コードはそれを呼び出す前にdoneの値をチェックする必要があります。そのため、if (done) done()が存在します。

NB:問題には関係ありませんが、不要なグローバル変数の作成を避けるには、varキーワード(またはletconst)を使用するよう注意してください。

+0

歓迎します;-) – trincot

0

作成されたすべての関数呼び出しがスタックに置かれます。この時点で

Step 1: constructTree 
Step 2: calls parseFiles 
Step 3: calls parseFiles 
. 
. 
. 
Step n-1: calls parseFiles 
Step n: cannot parse any further 

、その問題を解決したり、別の懸念を持っている場合、私に教えてください

バック

Step n-1 
Step n-2 
. 
. 
. 
Step 3 
Step 2 
Step 1 - and pointer returns to the original caller 
を行くを開始します。