在 Node.js 中的单个 HTTP 请求中调用多个 HTTP 请求
Posted
技术标签:
【中文标题】在 Node.js 中的单个 HTTP 请求中调用多个 HTTP 请求【英文标题】:Calling multiple HTTP requests in a single HTTP request in Node.js 【发布时间】:2016-03-29 22:25:28 【问题描述】:我正在尝试在单个 URL 调用中调用多个 URL,并将其 json 响应推送到一个数组中,然后将该数组发送给最终用户。
我的代码如下所示:
var express = require('express');
var main_router = express.Router();
var http = require('http');
urls = [
"http://localhost:3010/alm/build_tool",
"http://localhost:3010/alm/development_tool",
"http://localhost:3010/alm/project_architecture"];
var responses = [];
main_router.route('/')
.get(function (req, res)
var completed_requests = 0;
for (url in urls)
http.get(url, function(res)
responses.push(res.body);
completed_request++;
if (completed_request == urls.length)
// All download done, process responses array
);
res.send(responses);
);
我也尝试过使用 npm 请求模块。 当我运行这段代码时,它只返回 NULL 或一些只有标题的随机输出。
我的目标是在单个节点获取请求中调用多个 URL,并将其 JSON 输出附加到数组中并发送给最终用户。
谢谢
【问题讨论】:
你必须使用回调或者我可以建议异步模块github.com/caolan/async 见this answer。您实际上应该使用res.on('end', function...
等待响应结束
【参考方案1】:
来,试试这段代码,
const async = require('async');
const request = require('request');
function httpGet(url, callback)
const options =
url : url,
json : true
;
request(options,
function(err, res, body)
callback(err, body);
);
const urls= [
"http://localhost:3010/alm/build_tool",
"http://localhost:3010/alm/development_tool",
"http://localhost:3010/alm/project_architecture"
];
async.map(urls, httpGet, function (err, res)
if (err) return console.log(err);
console.log(res);
);
说明:
此代码使用async 和request 节点包。 async.map
根据定义需要 3 个参数,第一个是一个数组,第二个是您要使用该数组的每个元素调用的迭代器函数,以及在 async.map 完成处理时调用的回调函数。
map(arr, iterator, [callback])
通过将 arr 中的每个值映射到 迭代器函数。使用 arr 中的项目调用迭代器 以及完成处理时的回调。这些中的每一个 回调有 2 个参数:一个错误,以及转换后的项目 arr。如果迭代器将错误传递给其回调,则主回调 (对于 map 函数)立即调用错误。
注意:对迭代器函数的所有调用都是并行的。
在您的 httpGet 函数中,您使用传递的 url 调用 request
函数,并明确告知响应格式为 json
。 request
,处理完成后,调用回调函数,带三个参数,err - 如果有,res - 服务器响应,body - 响应正文。
如果request
中没有err
,async.map
将这些回调的结果作为一个数组收集,并在最后将该数组传递给它的第三个回调函数。否则,如果 (err) 为真,async.map
函数将停止执行并使用 err
调用其回调。
【讨论】:
这里的request
是什么? async
怎么样?在答案中使用库很好,但前提是您指定要使用的库:P
好吧,asker 似乎已经知道这些包了。无论如何,为其他用户更新。
感谢您。是否可以将所有数据主体合并为一个?如果我从多个 URls i.imgur.com/nX1IRla.png 下载 JSON 格式,这就是我的样子。您知道如何将它们合并到 1 个数据体下吗?
您可以简单地遍历每个响应正文并将其添加到您的最终正文中。但是,如果您使用分页,请小心。【参考方案2】:
我建议使用async 库。
async.map(urls, http.get, function(err, responses)
if (err)
// handle error
else
res.send responses
)
上面的 sn-p 将对每个 url 并行执行 http.get
调用,并在收到所有响应后使用所有调用的结果调用您的回调函数。
如果要串联调用url,可以使用async.mapSeries
。如果你想限制并发请求的数量,你可以使用async.mapLimit
。
【讨论】:
感谢您的评论。如果您有任何可用的代码,请分享。我尝试了以下代码,但没有得到任何响应。 main_router.route('/') .get(function (req, res) var test = async.each(urls, http.get, function(err, response, callback) if (err) // 处理错误 else 返回响应; ) res.send(test); res.end(); ); 注意:async.each
回调不处理响应。如果您在调用结束时需要响应,您应该使用async.map
,它将在您的回调函数中以数组的形式响应每个 HTTP 请求。以上是关于在 Node.js 中的单个 HTTP 请求中调用多个 HTTP 请求的主要内容,如果未能解决你的问题,请参考以下文章
如何从Google Cloud Function(Cheerio,Node.js)发出多个http请求