2013-06-14 3 views
3

Je voudrais lancer des appels HTTP asynchrones sur mon nœud de serveur, j'ai vu le module de noeud async et je suppose que le async.parallel nous permet de faire cela.Appels HTTP asynchrones avec nodeJS

L'exemple documenté est assez clair, mais je ne sais pas comment gérer plusieurs appels http.

J'ai essayé l'exemple ci-dessous, mais il n'a même pas lancer les appels http:

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

Si je lance i faire les requêtes http séparément, un résultat, mais, mais appeler le rappel async je reçois async callback: [null,null]

+0

requête HTTP sont déjà asynchrone dans Node.js. – aggsol

+0

oui mais j'ai besoin d'obtenir les deux réponses en même temps pour rendre une page web – Ludo

+0

Vous ne les obtiendrez jamais en même temps car node.js est single threaded et chaque requête vient dans l'ordre. Vous devez juste attendre que le second rappel soit appelé. Le comptage de rappel simple aidera. – aggsol

Répondre

5

Jetez un oeil à 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.

vous créez une demande, mais vous n'êtes pas finalisera. Dans vos appels, vous devriez faire:

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

Ceci suppose que vous faites une requête GET normale sans corps.

Vous devriez également envisager d'utiliser http.get qui est un raccourci agréable:

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

Mise à jour L'autre chose est que callbacks dans async doivent être de la forme

function(err, res) { ... } 

La façon dont vous le faire maintenant ne fonctionnera pas, car le rappel à http.get n'accepte qu'un seul argument res. Ce que vous devez faire est la suivante:

http.get('http://127.0.0.1:3002/second', function(res) { 
    callback(null, res); 
}); 
+0

Merci pour les conseils! Mais le rappel Async ne fonctionne toujours pas. – Ludo

+0

@Ludo J'ai mis à jour la réponse. – freakish

+0

Et si je devais faire près de 1000 demandes !!!! il me donne erreur événements.js: 141 throw er; // 'erreur' Unhandled l'événement ^ Erreur: prise raccrocher à createHangUpError (_http_client.js: 202: 15) à Socket.socketOnEnd (_http_client.js: 287: 23) à emitNone (événements.js: 72: 20) à Socket.emit (events.js: 166: 7) à endReadableNT (_stream_readable.js: 905: 12) à nextTickCallbackWith2Args (Node.js: 441: 9) à process._tickDomainCallback (node.js: 396: 17) – vkstack

0

Ok la chose est d'appeler le rappel de cette façon callback(null, res); à la place callback(res);, je pense que le premier paramètre est interprété comme une erreur et le second est le résultat réel.

1

DonT utiliser des noms de capital pour d'autres types purpouses que les classes/

ci-dessous est votre code avec des erreurs évidentes corrigées

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); 
}); 
+0

Et si je devais faire près de 1000 demandes !!!! cela me donne l'erreur events.js: 141 throw er; // Evénement 'error' non géré^Erreur: le socket se bloque à createHangUpError (_http_client.js: 202: 15) à Socket.socketOnEnd (_http_client.js: 287: 23) à emitNone (events.js: 72: 20) à Socket .emit (events.js: 166: 7) at endReadableNT (_stream_readable.js: 905: 12) at nextTickCallbackWith2Args (node.js: 441: 9) à l'adresse process._tickDomainCallback (node.js: 396: 17) – vkstack

+0

Vous pouvez essayer à es6 Promettez l'appel http, puis utilisez quelque chose comme Promise.all() – Prozi

Questions connexes