簡體   English   中英

執行延遲的HTTP請求的NodeJS隊列很奇怪

[英]NodeJS Queue performing delayed HTTP Request are weird

親愛的互聯網上樂於助人的人,我開始編寫HTTP隊列。 我有一個請求類, 如果我在沒有上下文的情況下使用它 ,該類將起作用 ,但是當我的隊列處於活動狀態時,我的http請求將無法工作。 我不知道為什么。

var t = new Request('s','s', function(){});
t.perform();

當我在任何文件中執行這樣的請求時。 有用。 但是,當我將其與隊列(index.js,L19至L22)一起使用時,不會執行任何請求。 函數Request.perform()已執行,但是HTTP-Request不存在。 對不起,我的英語不是我的母語^^

index.js

const http    = require('http');
const https   = require('https');
const {Request} = require('./classes/Request');
const queue   = require('./queue.js');

queue.setCallbackFunction(performRequest);
function performRequest(request){
    console.log("2");
    request.perform();
}
var req = new Request('','', function(response,body){
   console.log(JSON.stringify(response) + " :: " + body);
});
queue.add(req);

queue.js

var queue = [];
var ratelimits = [];

module.exports.add = function(request){
    queue.push(request);
    run_queue();
}
module.exports.setCallbackFunction = function(cb){
    call = cb;
}
module.exports.setRateLimits = function(ratelimitings){
    ratelimits = [];
    for(var z in ratelimitings){
        var x = ratelimitings[z];
        var data = {};
        data.max = x[0];
        data.time = x[1];
        data.count = 0;

        ratelimits[x[1]] = data;
    }
}
function run_queue(){
    var q;
    if(queue.length > 0){
        q = run_request(queue[0]);
        while (q == true) {
            queue.shift();
            if(queue.length > 0)
            q = run_request(queue[0]);
        }
    }
}

function run_request(request){
    for(var z in ratelimits){
        var x = ratelimits[z];
        if(x.max <= x.count){
            return false;
        }
    }
    for(var z in ratelimits){
        var x = ratelimits[z];
        if(x.count === 0){
            setTimeout(function(z){
                console.log(JSON.stringify(x));
                ratelimits[z].count = 0;
                run_queue();
            },z,z);
        }
        x.count++;
        //console.log(JSON.stringify(x));
    }
    //DO REQUEST
    console.log("1")
    call(request);
    return true;
}

Request.js

exports.Request = class{
    constructor(host,path,cb){
        this.path = path;
        this.cb = cb;
        this.host = host
    }
    perform(){
        console.log("3");
        var https = require('https');
        var options = {
            host: 'www.example.com',
            path: '/'
        };

        var callback = function(response) {
        //HERE THIS GETS NEVER CALLED BECAUSE OF WHATEVER WHILE ITS IN THE QUEUE
            var str = '';
        //another chunk of data has been recieved, so append it to `str`
            response.on('data', function (chunk) {
                str += chunk;
            });

            //the whole response has been recieved, so we just print it out here
            response.on('end', function () {
                console.log(str);
            });
        }

        https.request(options, callback).end();
    }
}

將打印所有3個console.log,但不會調用“請求回調”。

問題是由功能run_queue引起的:

function run_queue(){
    var q;
    if(queue.length > 0){
        q = run_request(queue[0]);
        while (q == true) {
            queue.shift();
            if(queue.length > 0)
            q = run_request(queue[0]);
        }
    }
}

成功執行run_request() (發送HTTP請求)后, queue.shift()立即調用queue.shift() ,這意味着將從queue數組中刪除剛剛添加到隊列中的req對象,並可以進行垃圾回收。 由於一個HTTP請求/響應通常會花費幾毫秒的時間,因此很有可能在檢索響應之前,已對req對象進行了GC(銷毀)。 因此,將不再調用回調,因為HTTP連接不再存在。

要更改隊列但保留GC中的req對象,您需要將其保存在其他地方,例如臨時數組(以下代碼中的無限循環錯誤也已修復):

var tmp = [];
function run_queue(){
    var q;
    if(queue.length > 0){
        q = run_request(queue[0]);
        while (q == true) {
            tmp.push(queue.shift());
            if(queue.length > 0) {
                q = run_request(queue[0]);
            } else {
                q = false;
            }
        }
    }
}

請注意,以上代碼僅用於演示。 在生產代碼中,您需要管理tmp數組-完成一個請求后,需要將其從tmp刪除。 否則, tmp數組將繼續增長...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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