![](/img/trans.png)
[英]nodejs: read from file and store to db, limit maximum concurrent db operations
[英]limit concurrent operations nodejs
这是用节点js编写的Web抓取代码。
当队列具有足够的URL时,此代码是否将始终保留5个并发请求?
为什么控制台显示其他内容?
var request = require("request");
var cheerio = require("cheerio");
var fs = require('fs');
var concurrent_requests = 0;
var queue = [];
var baseUrl = "https://angularjs.org/";
function makeApiCall(url){
if(url) {
queue.unshift(url);
}
if(concurrent_requests<5) {
var nextUrl = queue.pop();
if(nextUrl) {
concurrent_requests++;
request(nextUrl, function (error, response, body) {
var invalidUrl;
concurrent_requests--;
if(body) {
var $ = cheerio.load(body);
var anchors = $("a");
var data = "";
for (var i = 0; i < anchors.length; i++) {
url = $(anchors[i]).attr("href");
if(!url || url === "#" || url === "javascript:void(0)"){
invalidUrl = true;
}
else{
invalidUrl = false;
}
if (!invalidUrl) {
makeApiCall(url);
data += url + ", " + nextUrl + "\n";
}
}
//console.log(data);
fs.appendFile('urls.csv',data, function (err) {
if (err) throw err;
});
}
else{
makeApiCall();
}
});
}
}
console.log(concurrent_requests);
}
makeApiCall(baseUrl);
Becoz,您有一个条件,要求使用if语句要求不要超过5个。
if(concurrent_requests <5){
该解决方案不可扩展,因为在某些递归调用之后将遍历整个堆栈。
希望能帮助到你。
您正在使用if条件检查并发请求数是否少于五个。 但是请记住,它是
if
语句,而不是循环。 这意味着它将仅被调用一次。您正在请求的回调内对函数
makeApiCall
进行递归调用。 请求的回调仅在满足请求时运行。
考虑到以上两点,在您的if条件下,您检查concurrent_requests<5
请求数是否concurrent_requests<5
然后调用请求方法,程序将变得理想。 在请求ID满足后的某个时间过后,请求的回调将运行,在某些逻辑之后,该回调将再次调用makeApiCall
。 因此,在每个调用中,您只调用一次请求,然后等待该请求解决,然后只有程序继续进行下一个请求。
如果您想要并发请求,则使用这样的循环
function makeApiCall(url){
if(url) {
queue.unshift(url);
}
// Use a loop here
while(concurrent_requests<5) {
var nextUrl = queue.pop();
if(nextUrl) {
concurrent_requests++;
request(nextUrl, function (error, response, body) {
var invalidUrl;
concurrent_requests--;
if(body) {
...
if (!invalidUrl) {
makeApiCall(url);
data += url + ", " + nextUrl + "\n";
}
}
...
}
else{
makeApiCall();
}
});
}
else{
// Remember to break out of loop when queue is empty to avoid infinite loop.
break;
}
}
console.log(concurrent_requests);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.