morfioce
morfioce

Reputation: 1117

Node.js flow control

My question is the following: I want to return the result returned by the callback.

exports.process_logs = function(file, process_func, process_parsedLog) {
var logs = [];
var log = null;
var counter = 0;
fs.readFile(file, 'utf8', function(read_error, content) {
    if (read_error) return sys.error(read_error);

    // TODO:: Remove these hardcode rails filters
    // switch filters and split functions to a nested helper in process func
    content.split(/Processing /).forEach(function(msg, index) {
        if ((tmp = process_func(msg, index)))
            logs.push(tmp);
    });
    log = process_parsedLog(logs);
});
console.log(log);
return log;

};

But the variable "log" still null, although when I check it with console.log(log) just after "log = process_parsedLog(logs);" gives the correct result.

Upvotes: 0

Views: 744

Answers (2)

pfried
pfried

Reputation: 5079

You have to do the return in the callback function of the filesystem. But the function stays asynchronous. You cannot use the return value instantly:

log = process_parsedLog(logs);
return log;
});

You should keep the functions asynchronous, if you want to have a module like this, add a callback function to your anonymous function you want to export, like:

exports.process_logs = function(file, process_func, process_parsedLog, callback)

When the fs is done it will call the callback you passed in by return callback(err, log)

You can use promises as well here to avoid a pyramid of callback functions.

Upvotes: 0

Daniel Uzunu
Daniel Uzunu

Reputation: 3246

The problem is that fs.readFile is an asynchronous function and the process_logs function finishes its execution before readFile invokes the callback you passed to it. You should use promises for these situations: https://github.com/kriskowal/q

exports.process_logs = function(file, process_func, process_parsedLog) {
    var deferred = Q.defer();
    var logs = [];
    var log = null;
    var counter = 0;
    fs.readFile(file, 'utf8', function(read_error, content) {
        if (read_error) deferred.reject(sys.error(read_error));

        // TODO:: Remove these hardcode rails filters
        // switch filters and split functions to a nested helper in process func
        content.split(/Processing /).forEach(function(msg, index) {
        if ((tmp = process_func(msg, index)))
            logs.push(tmp);
        });
        log = process_parsedLog(logs);
        deferred.resolve(log);
    });
    // the result is not available yet
    return deferred.promise;
};

Upvotes: 1

Related Questions