Kristian Roebuck
Kristian Roebuck

Reputation: 3379

How to return a value from a callback

I'm using node.js to perform a DNS lookup to return and IP address (http://nodejs.org/api/dns.html). In this example, I can get my result to log correctly, though I'd rather be able to have access to the variable outside of the scope of the callback. How would this be possible?

My current code:

var domain = 'google.co.uk';

dns.lookup(domain, function (err, aRecord) {
    if (err) throw err;
    console.log(aRecord);
});

Ideally, I'd like to be able to perform something along the lines of:

var domain = 'google.co.uk';

var myfunction = dns.lookup(domain, function (err, aRecord) {
    if (err) throw err;
    return aRecord;
});

var result = myfuction(domain);

Upvotes: 1

Views: 949

Answers (3)

Andbdrew
Andbdrew

Reputation: 11895

You can (and should) use a Promise, like Simon suggested. Barring typos, the following should work.

var Q = require('q');

var domain = 'google.co.uk';

function myFunction(domain){

    var deferred = Q.defer();

    dns.lookup(domain, function (err, aRecord) {
        if (err) {
            return deferred.reject(err);
        }
        deferred.resolve(aRecord);
    });

    return deferred.promise;
}    

var lookupPromise = myFunction(domain);

lookupPromise.then(function(response){
    console.log(response);
})

One nice thing about this approach is that you can pass promises around as arguments to other functions. Then you can write a function that uses the data returned by your dns lookup function by having it accept (and return) a promise.

function useLookup(lookupPromise){
    var deferred = Q.defer();

    lookupPromise.then(function(lookupResponse){
        deferred.resolve(lookupResponse);
    }).fail(function(err){
        deferred.reject(err);
    })

    return deferred.promise;
}

Upvotes: 1

Simon Boudrias
Simon Boudrias

Reputation: 44649

As is, that's not possible as it is asynchronous. You can place all your code inside the callback, but that's may not be the best.

One way developer can deal with asynchronous action returning data is using Promises. The best article I've ever read about promise concept is this one: http://blog.jcoglan.com/2013/03/30/callbacks-are-imperative-promises-are-functional-nodes-biggest-missed-opportunity/ Give it a read!

In node, a well known promise library is Q: https://github.com/kriskowal/q

If you want more conceptual approah to the async behavior/management in Javascript, there's a really good book by Trevor Burnham called "Async Javascript" http://pragprog.com/book/tbajs/async-javascript

Upvotes: 2

shift66
shift66

Reputation: 11958

You can't. Javascript is asynchronous. You have to place all your code with logic into callback.

Javascript will continue executing your code after var result = myfuction(domain); and won't wait the callback to be executed. And your function will return nothing (undefined) as a result

Upvotes: 0

Related Questions