【问题标题】:Asynchronous http calls with nodeJS使用 nodeJS 进行异步 http 调用
【发布时间】:2026-02-01 19:25:02
【问题描述】:

我想在我的服务器节点上启动异步 http 调用,我看到了 async 节点模块,我猜 async.parallel 使我们能够做到这一点。

文档中的示例非常清楚,但我不知道如何管理多个 http 调用。

我尝试了下面的示例,但它甚至没有启动 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);
});

如果我单独启动 http 请求,我确实有结果,但调用异步回调我得到async callback: [null,null]

【问题讨论】:

  • HTTP 请求在 node.js 中已经是异步的了。
  • 是的,但我需要同时获得两个响应来呈现网页
  • 你永远不会同时得到它们,因为 node.js 是单线程的,每个请求都是按顺序来的。你只需要等到第二个回调被调用。简单的回调计数会有所帮助。
  • 是的,当调用第二个回调时,我可以通过启动与它们联系的新回调(或使用异步节点模块)同时获得这两个结果:-)

标签: node.js http node-async


【解决方案1】:

看看the documentation:

使用 http.request() 必须始终调用 req.end() 来表示 您已完成请求 - 即使没有写入数据 到请求正文。

您正在创建一个请求,但您没有完成它。在您的通话中,您应该这样做:

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

这是假设您正在执行没有正文的普通 GET 请求。

您还应该考虑使用http.get,这是一个不错的快捷方式:

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

更新另一件事是异步回调必须是形式

function(err, res) { ... }

你现在的做法行不通,因为对 http.get 的回调只接受一个参数res。您需要做的是:

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

【讨论】:

  • 感谢您的提示!但是异步回调仍然不起作用。
  • 如果我必须提出近 1000 个请求怎么办!!!!它给了我错误 events.js:141 throw er; // 未处理的 'error' 事件 ^ 错误:socket 在 Socket.socketOnEnd (_http_client.js:287:23) 处的 createHangUpError (_http_client.js:202:15) 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)
【解决方案2】:

好的,事情是以这种方式调用回调callback(null, res); 而不是callback(res);,我认为第一个参数被解释为错误,第二个是真正的结果。

【讨论】:

    【解决方案3】:

    不要将大写名称用于类型/类以外的其他目的

    下面是你的代码,纠正了明显的错误

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

    【讨论】:

    • 如果我必须提出近 1000 个请求怎么办!!!!它给了我错误 events.js:141 throw er; // 未处理的“错误”事件 ^ 错误:socket 在 Socket.socketOnEnd (_http_client.js:287:23) 处的 createHangUpError (_http_client.js:202:15) at emitNone (events.js:72:20) 处挂起.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)
    • 你可以尝试 es6 Promise http 调用,然后使用 Promise.all() 之类的东西