1

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);
Kristian Roebuck
  • 3,209
  • 2
  • 21
  • 29
  • It's not possible. If it was, you would not have to provide a callback. See the first part of [my answer here](http://stackoverflow.com/a/14220323/218196) for an explanation of synchronous and asynchronous code. – Felix Kling Apr 19 '13 at 14:41
  • Potential Dup of this dup of dups: http://stackoverflow.com/questions/6847697/how-to-return-value-from-callback-function. – Mogsdad Apr 19 '13 at 14:42
  • A reasonable work-around is described [here](http://stackoverflow.com/a/6847754/1677912). – Mogsdad Apr 19 '13 at 14:44

3 Answers3

2

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

Simon Boudrias
  • 42,953
  • 16
  • 99
  • 134
1

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;
}
Andbdrew
  • 11,788
  • 4
  • 33
  • 37
0

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

shift66
  • 11,760
  • 13
  • 50
  • 83