2017-02-28 60 views
-4

我有搜索功能,一旦我有搜索字符串從clinet我想循環通過文件和匹配來自FS中的文件的字符串,我有循環中的問題我想獲得所有匹配結果並將結果發送到客戶端。下面試圖實現,但得到一個錯誤粘貼有問題。新的異步庫任何幫助將不勝感激。如何使用nodejs使用異步回調?

app.js

app.get('/serverSearch', function (req, res) { 
    var searchTxt = req.query.searchTxt; 
    dirDirectory.readDirectory(function(logFiles){ 
     // res.json(logFiles); 
     if(logFiles){ 
      searchFileService.readFile(searchTxt,logFiles,function(lines,err){ 
         console.log('Logs',lines); 
          if (err) 
          return res.send(); 
          res.json(lines); 
        }) 

     } 
    }); 

    console.log('Search text', searchTxt); 
}); 

service.js

var fs = require('fs'); 
var path = require('path'); 
var async = require('async'); 
var searchStr; 
var result = []; 


//Async Method 
function readFile(str, logFiles, callback) { 
    async.series([ 
     //Load user to get `userId` first 
     function(callback) { 
      searchStr = str; 
      for (var i = 0; i < logFiles.length; i++) { 
       if (logFiles[i].filename !== '.gitignore') { 
        fs.readFile('logs/dit/' + logFiles[i].filename, 'utf8', function(err, data) { 
         if (err) { 
          return console.log(err); 
         } 
         inspectFile(data); 
        }); 
       } 
       callback(result); 
      } 
     }, 
     //Load posts (won't be called before task 1's "task callback" has been called) 
     function() { 
      function inspectFile(data, callback) { 
       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 
         result.push(line); 
         // then log it 
         return line; 
        } 
       }); 
      } 
     } 
    ], function(err) { //This function gets called after the two tasks have called their "task callbacks" 
     if (err) return err; 
    }); 
}; 

錯誤

if (fn === null) throw new Error("Callback was already called."); 

回答

1

您應該使用async.map而不是系列。你很想知道系列做了什麼,系列處理請求自上而下。您正嘗試通過訪問該系列中的某個功能來打破此鏈。這是一個不,不。

例如:

async.series([ 
    function() { 
     let i = 0; 
     do { 
      console.log("I'm first in the series: ", i); 
      i++; 
     } while (i < 3); 
     callback(); // This tells us this function has finished. 
    }, 
    function() { 
     let i = 0; 
     do { 
      console.log("I'm next in the series: ", i); 
      i++; 
     } while (i < 3); 
     callback(); // This tells us this function has finished. 
    } 
]); 

這樣做的輸出將是:

I'm next in the series: 0

I'm next in the series: 1

I'm next in the series: 2

直到回調進行燒製,然後告訴同步以移動到串聯陣列中的下一個功能。然後

輸出將是:

I'm last in the series: 0

I'm last in the series: 1

I'm last in the series: 2

在這個系列沒有意義,你應該可以在當前後的系列中訪問該功能。所以你永遠不應該試圖跨越那個。

使用async.map您實際上可以對數組中的每個實體執行操作,這基本上就是您正在嘗試執行的操作。

var results = []; 
async.map(logFiles, function(logfile, callback) { 
    if (logfile.filename !== '.gitignore') { 
     fs.readFile('logs/dit/' + logfile.filename, 'utf8', function(err, data) { 
      if (err) { 
       callback(err, null); 
      } 
      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(null, results); 
       } 
      }); 
    } 
}), function(error, result) { 
    results.map(result => { 
     console.log(result); 
    }); 
}); 

此外,你應該使用util.inspect而不是console.log,它更清潔,有更多的選擇。

關於此的文檔有點粗糙,但在這裏。 https://caolan.github.io/async/docs.html#map希望這有助於!

+0

有在你的代碼中的一些語法問題,我試圖解決 – hussain

+0

啊對不起,我是混合ES6和ES5但它應該是接近你所需要的。希望能幫助到你! – djowinz

+0

我是否必須從'readFile'功能以及 – hussain

0

你應該使用async.eachSeries method

function readFile(str, logFiles, callback) { 
    async.eachSeries(array, function(item, cb){ 
     //Process item 
     cb(error,item); 
    }, function(err){ 
     if (err) { 
      console.log("Some error in one of the items"); 
      callback(err); 
     } else { 
      console.log("All arrays items have been treated successfully"); 
      callback(null); 
     } 
    }); 
} 

而我會建議加載用戶帖子之前使用async.eachSeries函數。

+0

你的代碼工作,其打印所有陣列成功的治療,但其不是現在@hussain什麼結果發送到客戶端 – hussain

+0

?我已經更新了答案。我不知道你還需要解決客戶端的回調。 – daniegarcia254