Writing async http returns in Nodejs

I realize this quesiton probably gets asked a million times but I'll try anyway. So I am used to Python and Ruby and 'blocking' imperative code blocks and objects and methods and trying to learn this newfangled Node thing for a project I joined. Try as I might, I can't quite wrap my head around async callbacks and passing return values.

Here's my code:

var getAnHttp = function getAnHttp (args, callback) {                   
  var req = http.request(args, callback);                               

  req.on('error', function(errmsg) {                                     
    console.log('problem with request\t' + errmsg.message);              
  });                                                                   

  req.end();                                                            
};                                                                      

var getWebPageBody = function getWebPageBody (res) {                    
  var pageRes = "";                                                     

  res.setEncoding('utf8');                                              
  res.on('data', function(requestBody) {                                
    pageRes = requestBody;                                              
    console.log('[ DEBUG ] BODY:\t' + pageRes);                         
  });                                                                   
  res.on('end', function() {                                            
    return pageRes;                                                     
  });                                                                   
};                                                                      

exports.captureLink = function captureLink(targetLink) {                
  getAnHttp(targetLink, getWebPageBody);                              
};

And actually calling it:

var crawl   = require('../grab_site');

var aGreatSite    = { hostname : 'hotwebcrawlingaction.xxx',
                      port     : 80,
                      path     : '/asyncpron',
                      method   : 'GET'
                    };

var something = crawl.captureLink(aGreatSite);

getWebPageBody will print my output, but I can't get my returns to bubble up through the funcitons. I know I'm calling something in a sync fashion that and some in async but I can't quite sort this out. While I could certainly just put this in one big function I'm trying to do this right, not hack it out.

Anyway sorry for a noob question--I feel like I'm trying to be functional and OOP+imperative at the same time--i see plenty of other examples but I'm trying not to cargo cult or hail mary this one.

Async functions will never return something that has to fetched with async. getWebPageBody in your case returns undefined, and then later your callbacks happen.

In synchronous programming you return a value. But in async, you provide it as an argument to a callback function.

So instead, make your function accept a callback argument, and simply call it when you are done.

var getWebPageBody = function(res, callback) {                    
  var pageRes = "";                                                     

  res.setEncoding('utf8');                                              
  res.on('data', function(requestBody) {                                
    pageRes = requestBody;                                              
    console.log('[ DEBUG ] BODY:\t' + pageRes);                         
  });                                                                   
  res.on('end', function() {
    callback(pageRes); // invoke callback
  });
};

// and call it
getWebPageBody(res, function(pageRes) {
  // pageRes is now the thing you expect, inside this function.
});

If you invoke a function which triggered async actions, return will never get any values out of that. It's all about callbacks. You fire your own callback, from the callback of something else.