ispilledthejava
ispilledthejava

Reputation: 193

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.

Upvotes: 0

Views: 974

Answers (1)

Alex Wayne
Alex Wayne

Reputation: 187262

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.

Upvotes: 4

Related Questions