简体   繁体   中英

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

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM