Codemator
Codemator

Reputation: 513

How to access a return value from a javascript async function

I have a Node.js function to fetch some value from DB table

var GetPoints = function(ibmdb, dbConnection, msisdn) {
    ibmdb.open(dbConnection, function(err, conn) {
        if (err) {
            //Error
        } else {
            conn.query('SELECT id,msisdn,points FROM t_points WHERE msisdn =' + msisdn, function(err, data) {
                console.log(err);
                if (!err) {
                    conn.close(function(err) {
                        if (!err) {}
                    });
                    consele.log(data);
                    //return data[0].POINTS;
                } else {
                    //Error
                }
            });
        }
        console.log("points" + points);
    });
}

I want to know how I can access the data object when I call this function from outside

 var data = GetPoints(ibmdb, dbConnection, msisdn);

The value is coming correctly when I do a console.log

Upvotes: 1

Views: 1123

Answers (2)

laggingreflex
laggingreflex

Reputation: 34627

You can't return the value from an async function directly. Promises are generally used this situation. You return a promise which can later be called .then upon to retrieve the said value.

var Promise = require('bluebird');
var GetPoints = function(ibmdb, dbConnection, msisdn) {
    // return a Promise
    return new Promise(function(resolve){
        ibmdb.open(dbConnection, function(err, conn) {
            if(err) throw err; // throw the error for it to be caught
            …
            conn.query('SELECT …', function(err, data) {
                if(err) throw err;
                …
                consele.log(data);
                //return data[0].POINTS;
                resolve(data);
}); }); }); }

GetPoints().then(function(data){
    // do something with data
}).catch(function(err){
    // handle err
});

Additionally, Bluebird has a promisify function that turns an async function (that takes a callback) into a function that returns a Promise. It makes the above code much simpler:

Note: Although I was reluctant because if you're using MySQL with which the promisification could be a little tricky: 1, 2. But For now I've added .promisifyAll where it might seem redundant as it will likely be executed more than once, but hopefully bluebird's promisification is smart enough to handle this. Nonetheless if you manage to promisify more efficiently you can just remove the redundant promisifyAll and just use X.yyyAsync methods as described:

function GetConnection(ibmdb, dbConnection, msisdn){
    Promise.promisifyAll(ibmdb);
    return ibmdb.openAsync();
}

function getData(conn){
    Promise.promisifyAll(conn);
    return conn.queryAsync('SELECT …');
}

GetConnection()
.then(getData)
.then(function(data){
    // do something with data        
})

Upvotes: 6

Ram Vennam
Ram Vennam

Reputation: 3546

The callback function you gave after the SQL query gets executed asynchronously. Instead of trying to get that data outside the function, you should try to perform whatever you need to do inside. Keep in mind you can create another function and call it with the data to continue your work.

Upvotes: 0

Related Questions