5

I would like to launch asynchronous http calls on my server node, i saw the async node module and i guess the async.parallel enables us to do that.

The documented example is pretty clear, but i don't know how i could manage multiple http calls.

I tried the example bellow but it doesn't even launch the http calls:

var http = require('http');

var Calls = [];
Calls.push(function(callback) {
    // First call
    http.get('http://127.0.0.1:3002/first' callback);
});

Calls.push(function(callback) {
    // Second call
     http.get('http://127.0.0.1:3002/second' callback);
});

var async = require('async');
async.parallel(Calls, function(err, results) {
    console.log('async callback: '+JSON.stringify(results));
    res.render('view', results);
});

If i launch the http requests separately, i do have a result, but but calling the async callback i get async callback: [null,null]

Ludo
  • 5,060
  • 15
  • 53
  • 85
  • HTTP request are already asynchronous in node.js. – aggsol Jun 14 '13 at 12:20
  • yes but i need to get the both responses at the same time to render a web page – Ludo Jun 14 '13 at 12:36
  • You will never get them at same time as node.js is single threaded and every request comes in order. You just have to wait till the second callback is called. Simple callback counting will help. – aggsol Jun 14 '13 at 13:46
  • yes, and when the second callback is called, i can get the both results at the same time by launching a new callback which contact them (or by using async node module) :-) – Ludo Jun 14 '13 at 14:39

3 Answers3

5

Have a look at the documentation:

With http.request() one must always call req.end() to signify that you're done with the request - even if there is no data being written to the request body.

You are creating a request, but you are not finalizing it. In your calls you should do:

var req = http.request(options, function(page) {
    // some code
});
req.end();

This is assuming you are doing a normal GET request without body.

You should also consider using http.get which is a nice shortcut:

http.get("http://127.0.0.1:3002/first", function(res) {
    // do something with result
});

Update The other thing is that callbacks in async have to be of the form

function(err, res) { ... }

The way you are doing it now won't work, because callback to http.get accepts only one argument res. What you need to do is the following:

http.get('http://127.0.0.1:3002/second', function(res) {
    callback(null, res);
});
freakish
  • 54,167
  • 9
  • 132
  • 169
  • Thanks for the tips ! But the Async callback still doesn't work. – Ludo Jun 14 '13 at 12:19
  • What if i have to make nearly 1000 requests!!!! it gives me error events.js:141 throw er; // Unhandled 'error' event ^ Error: socket hang up at createHangUpError (_http_client.js:202:15) at Socket.socketOnEnd (_http_client.js:287:23) at emitNone (events.js:72:20) at Socket.emit (events.js:166:7) at endReadableNT (_stream_readable.js:905:12) at nextTickCallbackWith2Args (node.js:441:9) at process._tickDomainCallback (node.js:396:17) – vkstack Feb 09 '16 at 15:11
0

Ok the thing is to call the callback this way callback(null, res); instead callback(res);, i think the first parameter is interpreted as an error and the second one is the real result.

Ludo
  • 5,060
  • 15
  • 53
  • 85
0

dont use capital names for other purpouses than types/classes

below is your code with corrected obvious mistakes

var http = require('http');

var calls = [];
calls.push(function(callback) {
    // First call
    http.get('http://127.0.0.1:3002/first', function (resource) {
         resource.setEncoding('utf8');
         resource.on('data', function (data) {
             console.log('first received', data);
             callback();
         });
    });
});

calls.push(function(callback) {
    // Second call
    http.get('http://127.0.0.1:3002/second', function (resource) {
         resource.setEncoding('utf8');
         resource.on('data', function (data) {
             console.log('second received', data);
             callback();
         });
    });
});

var async = require('async');
async.parallel(calls, function(err, results) {
    console.log('async callback ', results);
    res.render('view', results);
});
Jacek Pietal
  • 1,980
  • 1
  • 18
  • 27
  • What if i have to make nearly 1000 requests!!!! it gives me error events.js:141 throw er; // Unhandled 'error' event ^ Error: socket hang up at createHangUpError (_http_client.js:202:15) at Socket.socketOnEnd (_http_client.js:287:23) at emitNone (events.js:72:20) at Socket.emit (events.js:166:7) at endReadableNT (_stream_readable.js:905:12) at nextTickCallbackWith2Args (node.js:441:9) at process._tickDomainCallback (node.js:396:17) – vkstack Feb 09 '16 at 15:13
  • You could try to es6 Promise the http call and then use something like Promise.all() – Jacek Pietal Jul 27 '16 at 21:55