Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 执行延迟HTTP请求的NodeJ队列很奇怪_Node.js_Http_Request_Queue - Fatal编程技术网

Node.js 执行延迟HTTP请求的NodeJ队列很奇怪

Node.js 执行延迟HTTP请求的NodeJ队列很奇怪,node.js,http,request,queue,Node.js,Http,Request,Queue,亲爱的互联网上乐于助人的人们:, 我开始编写一个HTTP队列。我有一个请求类,如果我在没有上下文的情况下使用它,会起作用,但是当我的队列处于活动状态时,我的http请求不会起作用。我不明白为什么 var t = new Request('s','s', function(){}); t.perform(); 当我在任何文件中执行这样的请求时。它起作用了。但当我将它用于队列(index.js,L19到L22)时,不会执行任何请求。已执行函数Request.perform(),但HTTP请求不存在

亲爱的互联网上乐于助人的人们:, 我开始编写一个HTTP队列。我有一个请求类,如果我在没有上下文的情况下使用它,会起作用,但是当我的队列处于活动状态时,我的http请求不会起作用。我不明白为什么

var t = new Request('s','s', function(){});
t.perform();
当我在任何文件中执行这样的请求时。它起作用了。但当我将它用于队列(index.js,L19到L22)时,不会执行任何请求。已执行函数Request.perform(),但HTTP请求不存在。 对不起我的英语,我不是本地人^^

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);
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;
}
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();
    }
}
queue.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);
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;
}
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\u 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\u request()
后(发送HTTP请求),立即调用
queue.shift()
,这意味着刚刚添加到队列中的
req
对象将从
queue
数组中移除,并符合垃圾收集的条件。由于一个HTTP请求/响应通常需要几毫秒的时间,因此很可能在检索响应之前,
req
对象被GCed(销毁)。因此,不会调用回调,因为HTTP连接不再存在

要更改队列但保留GC中的
req
对象,您需要将其保存到其他地方,例如临时数组(以下代码中还修复了无限循环错误):


请注意以上代码仅用于演示。在生产代码中,您需要管理
tmp
数组——当一个请求完成时,需要将其从
tmp
中删除。否则,
tmp
阵列将继续增长…

谢谢!我试试这个。听起来很有逻辑。不。。。不起作用。。。很抱歉但感谢您的帮助hmmm…@qry,我在中创建了一个完整的示例,运行后,您可以看到caniuse.com的html内容打印在控制台中(调用请求回调)。希望对你有帮助。