簡體   English   中英

限制並發操作nodejs

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM