简体   繁体   中英

Callback is already called using async?

Once fs.readFile loop through all files and get the matching data and push it to results, I want to call callback(results) so i can send response to client. I am getting an error with below code Error: Callback is already called HOw can i resolve this issue using async approach.

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

Note: this answer is an extension to trincot's answer . So if this answers your question, kindly mark his as the answer!

You said: Once fs.readFile loop through all files and get the matching data and push it to results then I don't think .map is the appropriate function for this, to be honest. This is for transforming every element from an array into another which is not what you are doing.

A better method would be .eachSeries to read one file at a time.

It's a good idea to rename your second callback to something else eg done to not confuse yourself (and others). Calling done() is for telling that the operation on the file is completed as in we are "done" reading the file.

Lastly, be careful with your typos. The first one may have prevented you from getting into the last part.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM