我有一个Nodejs应用程序,旨在对大型Web应用程序执行简单的端到端测试。此应用使用mikeal/Request和Cheerio模块在应用程序中导航,请求,遍历和检查网页。
我们正在重构一些测试,并且在串行调用多个request
函数时遇到问题。我相信这可能是由于Node.js进程达到了MaxSockets限制,但我并不完全确定。
一些代码......
var request = require('request');
var cheerio = require('cheerio);
var async = require('async');
var getPages_FromMenuLinks = function() {
var pageUrl = 'http://www.example.com/app';
async.waterfall([
function topPageRequest(cb1) {
var menuLinks = [];
request(pageUrl, function(err, resp, page) {
var $ = cheerio.load(page);
$('div[class*="sub-menu"]').each(function (i, elem) {
menuLinks.push($(this).find('a').attr('href');
});
cb1(null, menuLinks);
});
}, function subMenuRequests(menuLinks, cb2) {
async.eachSeries(menuLinks, functionv(link, callback) {
request(link, function(err, resp, page) {
var $ = cheerio.load(page);
// do some quick validation testing of elements on the expected page
callback();
});
}, function() { cb2(null) } );
}
], function () { });
};
module.export = getPages_FromMenuLinks;
现在,如果我运行此Node脚本,它将运行第一个topPageRequest
并启动subMenuRequests
,但在完成第三个子菜单项的请求后会冻结。
似乎我可能在Node或我的机器上遇到Max-Sockets限制(?) - 我在标准的Windows 8机器上测试它,运行Node v0.10.26。
我尝试过使用request({pool:{maxSockets:25}, url:link}, function(err, resp...
,但似乎没有任何区别。
如果我首先实例化它(如找到here),似乎还有一种方法可以中止请求对象。但我不知道如何“解析”page
,类似于上面代码中发生的情况。换句话说,从找到的解决方案in the link ...
var theRequest = request({ ... });
theRequest.pipe(parser);
theRequest.abort();
...,我如何将代码重新编写为pipe
并“解析”请求?
答案 0 :(得分:1)
您可以同时轻松地提出数千个请求(例如,来自单个for loop
),并且一旦提供特定请求,它们将排队并逐个自动终止。
我认为默认情况下每个域有5个套接字,在你的情况下这个限制应该足够了。
很可能您的服务器无法正确处理您的请求(例如,错误时它们不会被终止并无限期挂起)。
您可以通过三个步骤找出正在发生的事情:
检查您是否发送了正确的请求 - 因为@mattyice发现您的代码中存在一些错误。
调查服务器代码以及处理请求的方式 - 对我而言,似乎服务器不会在第一时间提供/终止它们。
在发送请求时尝试使用setTimeout
。 5000ms应该是合理的等待时间。超时时,请求将以适当的错误代码中止。
作为建议:我建议您使用一些更合适,更易于使用且更准确的工具来进行测试:例如: phantomjs。