2017-02-28 7 views
0

fs.readFileすべてのファイルをループして一致するデータを取得して結果にプッシュすると、callback(results)に電話してクライアントに応答を送信できます。私は以下のコードでエラーが発生しますError: Callback is already calledasyncアプローチを使用してこの問題を解決できます。コールバックはすでにasyncを使用して呼び出されていますか?

app.js

searchFileService.readFile(searchTxt, logFiles, function(lines, err) { 
    console.log('Logs', lines); 
    if (err) 
     return res.send(); 
    res.json(lines); 
}) 

readFile.js

var searchStr; 
var results = []; 

function readFile(str,logFiles,callback){ 
    searchStr = str; 
    async.map(logFiles, function(logfile, callback) { 
      fs.readFile('logs/dit/' + logfile.filename, 'utf8', function(err, data) { 
       if (err) { 
        callback(null,err); 
       } 
       var lines = data.split('\n'); // get the lines 
       lines.forEach(function(line) { // for each line in lines 
        if (line.indexOf(searchStr) != -1) { // if the line contain the searchSt 
         results.push(line); 
         callback(results,null); 
        } 
       }); 
      }); 
    }), function(error, result) { 
     results.map(result,function (result){ 
      console.log(result); 
     }); 
    }; 
} 
+0

callback(results、null); OK結果で –

+0

がapp.jsにあります。最初に 'function(err、lines)'のようなエラーが発生しました。 – hussain

+0

はい、しかしOKになると、パラメータは逆になります –

答えて

2

注:この答えはtrincot's answerに拡張したものです。だから、これがあなたの質問に答えるなら、親切に彼を答えとしてマークしてください!

あなたが言った:すべてのファイルを通じてfs.readFileループ一度とのマッチングデータを取得し、結果にプッシュし、私は正直に言うと、.mapは、このための適切な関数であるとは思いません。これは、配列のすべての要素を、あなたがやっていない要素に変換するためのものです。

一度に1つのファイルを読み取るより良い方法は.eachSeriesです。

第2のcallbackの名前を別の名前に変更することをお勧めします。 done自分自身(と他人)を混同しないように。 done()を呼び出すのは、ファイルの読み込みが「完了」されているため、ファイルの操作が完了したことを伝えるためです。

最後に、誤植に注意してください。最初のものはあなたが最後の部分に入るのを妨げているかもしれません。

var results = []; 
var searchStr; 

function readFile(str, logFiles, callback) { 
    searchStr = str; 
    // loop through each file 
    async.eachSeries(logFiles, function (logfile, done) { 
     // read file 
     fs.readFile('logs/dit/' + logfile.filename, 'utf8', function (err, data) { 
      if (err) { 
       return done(err); 
      } 
      var lines = data.split('\n'); // get the lines 
      lines.forEach(function(line) { // for each line in lines 
       if (line.indexOf(searchStr) != -1) { // if the line contain the searchSt 
        results.push(line); 
       } 
      }); 
      // when you are done reading the file 
      done(); 
     }); 

    // wrong: }), function (err) { 
    }, function (err) { 
     if (err) { 
      console.log('error', err); 
     } 
     console.log('all done: ', results); 

     // wrong: results.map(result, function (result){ 
     results.map(function (result){ 
      console.log(result); 
     }); 

     // send back results 
     callback(results); 
    }); 
} 
+0

私はクライアント側に 'results'を得ました。私が同じ文字列を2回検索した場合は2回、同じ配列をプッシュして2行目として送信する場合#2異なる検索であれば2回目の結果、最初に結果がレンダリングされます。文字列値は、最初の検索の結果を送信します。 – hussain

+0

@Mikey、よく発覚しました。二重の 'callback'変数が私の答えに私を混乱させました。私はそれを削除します(+1)。 – trincot

+0

@hussain、あなたの質問にはっきりと答えられているので、新しい質問としてフォローアップの質問をしてください。 – trincot

関連する問題