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);
3
  • It's not possible. If it was, you would not have to provide a callback. See the first part of my answer here for an explanation of synchronous and asynchronous code. Commented Apr 19, 2013 at 14:41
  • Potential Dup of this dup of dups: stackoverflow.com/questions/6847697/…. Commented Apr 19, 2013 at 14:42
  • A reasonable work-around is described here. Commented Apr 19, 2013 at 14:44

3 Answers 3

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

Sign up to request clarification or add additional context in comments.

Comments

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;
}

Comments

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

2 Comments

JavaScript is not asynchronous by itself, but most node methods are asynchronous.
Just what I meant :) Operators are called one after another of course.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.