有没有办法限制在节点js中同时执行的并发Q承诺的数量?
我正在构建一个webscraper,它必须请求和解析3000多个页面,并且在不限制的情况下,我的一些请求没有得到及时响应,因此连接停止,所需的响应(html代码)变得不可用。
为了解决这个问题,我发现限制请求的数量我的问题就消失了。
我尝试过以下方法,但没有效果:
- Concurrency limit in Q promises - node
- How can I limit Q promise concurrency?
- https://gist.github.com/gaearon/7930162
- https://github.com/ForbesLindesay/throat
我需要请求一个url数组,一次只做一个请求,当数组中的所有url都完成后,返回数组中的结果。
function processWebsite() {
//computed by this stage
urls = [u1,u2,u3,u4,l5,u6,u7,u8,u9];
var promises = throttle(urls,1,myfunction);
// myfunction returns a Q promise and takes a considerable
// amount of time to resolve (approximately 2-5 minutes)
Q.all(promises).then(function(results){
//work with the results of the promises array
});
}
4条答案
按热度按时间jv4diomz1#
我会这样做,它将迭代每个URL,构建一个承诺链,在前一个完成时运行,并使用请求结果数组进行解析。
你也可以把它变成一个帮手:
注意,
bluebird
promise库有一个帮助器来简化这类事情。rqdpfwrv2#
下面是我尝试为Q创建一个节流的
map
函数。它接受
items
数组(在您的示例中为URL),worker
(必须是接受项目并返回承诺的函数)concurrent
个项目。它回来了
它没有失败,你必须检查个别承诺,以确定整体的运作状态。
在您的情况下,您可以这样使用它,例如15个并发请求:
4ioopgfo3#
您可以在
then()
块中请求新的url当然,这是它的动态行为,我会维护一个队列,一旦一个承诺被解析,就从队列中取出一个url,然后再发出另一个请求,也许还有一个hash对象将url和结果联系起来。
第二次拍摄:
2o7dmzc54#
没有外部库。只有普通的JS。
如果您真的只需要一次一个请求,那么使用async/await就很容易:
如果您需要一次超过1个请求,那么可以使用递归来解决。
其思想是,最初我们立即获取允许的最大页数,并且每个请求在完成时都应该递归地启动一个新请求。
在本例中,我将成功的响应与错误一起填充,并处理所有页面,但如果您希望在第一次失败时终止批处理,则可以稍微修改算法。