Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return value from Node.js module with asynchronous function

I wrote a module for my Node.js project which processes some data and is supposed to return the result, like that:

var result = require('analyze').analyzeIt(data);

The problem is that analyze.js depends on an asynchronous function. Basically it looks like this:

var analyzeIt = function(data) {
    someEvent.once('fired', function() {
        // lots of code ...
    });
    return result;
};
exports.analyzeIt = analyzeIt;

Of course, this cannot work because result is still empty when it is returned. But how can I solve that?

like image 722
wortwart Avatar asked Feb 04 '15 15:02

wortwart


People also ask

How do you return a value from async in NodeJS?

We have to call the async function from another function which can be asynchronous or synchronous (We can pass the array or choose to declare the array in the async function itself) and then return the array from the async function.

Can an async function return a value?

Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise. Note: Even though the return value of an async function behaves as if it's wrapped in a Promise.resolve , they are not equivalent.

Can you return from an async function JavaScript?

Async functions will always return a value. Using async simply implies that a promise will be returned, and if a promise is not returned, JavaScript automatically wraps it in a resolved promise with its value.


1 Answers

You solve it the same way Node solves it in its API: With a callback, which might be a simple callback, an event callback, or a callback associated with a promise library of some kind. The first two are more Node-like, the promise stuff is very au currant.

Here's the simple callback way:

var analyzeIt = function(data, callback) {
    someEvent.once('fired', function() {
        // lots of code ...

        // Done, send result (or of course send an error instead)
        callback(null, result); // By Node API convention (I believe),
                                // the first arg is an error if any,
                                // the second data if no error
    });
};
exports.analyzeIt = analyzeIt;

Usage:

require('analyze').analyzeIt(data, function(err, result) {
    // ...use err and/or result here
});

But as Kirill points out, you might want to have analyzeIt return an EventEmitter and then emit a data event (or whatever event you like, really), or error on error:

var analyzeIt = function(data) {
    var emitter = new EventEmitter();

    // I assume something asynchronous happens here, so
    someEvent.once('fired', function() {
        // lots of code ...

        // Emit the data event (or error, of course)
        emitter.emit('data', result);
    });

    return emitter;
};

Usage:

require('analyze').analyzeIt(data)
    .on('error', function(err) {
        // ...use err here...
    })
    .on('data', function(result) {
        // ...use result here...
    });

Or, again, some kind of promises library.

like image 168
T.J. Crowder Avatar answered Oct 03 '22 01:10

T.J. Crowder