Javascript 如何获得待定承诺的数量?

Javascript 如何获得待定承诺的数量?,javascript,promise,ecmascript-6,Javascript,Promise,Ecmascript 6,我正在尝试创建一个函数,该函数使用以下逻辑发送HTTP请求: 如果有5个或更多正在进行的请求,则必须将下一个请求推迟到其中一个请求完成。只有这样,才能处理下一个请求 当响应代码不是200时,我希望重试请求最多3次。如果重试3次后的响应代码仍然不是200,则应执行错误函数 我如何知道正在进行的请求的数量?我怎样才能等到其中一个请求完成,然后才能处理下一个请求 以下是我到目前为止所做的尝试。count变量用于计算失败次数,但我不知道如何计算挂起的HTTP请求: var count = 0; f

我正在尝试创建一个函数,该函数使用以下逻辑发送HTTP请求:

  • 如果有5个或更多正在进行的请求,则必须将下一个请求推迟到其中一个请求完成。只有这样,才能处理下一个请求
  • 当响应代码不是200时,我希望重试请求最多3次。如果重试3次后的响应代码仍然不是200,则应执行错误函数
我如何知道正在进行的请求的数量?我怎样才能等到其中一个请求完成,然后才能处理下一个请求

以下是我到目前为止所做的尝试。count变量用于计算失败次数,但我不知道如何计算挂起的HTTP请求:

var count = 0;

function get(url) {
    return new Promise(function(resolve, reject) {
        var xhttp = new XMLHttpRequest();
        xhttp.open("GET", url, true);
        xhttp.onload = function() {
            if (xhttp.status == 200) {
                resolve(JSON.parse(xhttp.response));
            } else if (xhttp.status != 200 && count != 3) {
                count++;
                resolve(JSON.parse(xhttp.response));
            } else if {
                reject(xhttp.statueText):
            } else(count == 3) {
                reject("you have reached the maximum number of tries")
            }
        }    
        xhttp.onerror = function() {
            reject(xhttp.statueText);
        };
        xhttp.send()
    });
}
var promise = get("data/tweets.json);
promise.then(function(tweets) {
    console.log(tweets);
};

我怎样才能做到这一点呢?

你的问题有点不清楚,但让我试着试一试

你不能得到待定的承诺,你需要将它们(或其中的一些)存储在某个地方

关于最多5个请求的部分:

var count = 0;

function get(url) {
    return new Promise(function(resolve, reject) {
        var xhttp = new XMLHttpRequest();
        xhttp.open("GET", url, true);
        xhttp.onload = function() {
            if (xhttp.status == 200) {
                resolve(JSON.parse(xhttp.response));
            } else if (xhttp.status != 200 && count != 3) {
                count++;
                resolve(JSON.parse(xhttp.response));
            } else if {
                reject(xhttp.statueText):
            } else(count == 3) {
                reject("you have reached the maximum number of tries")
            }
        }    
        xhttp.onerror = function() {
            reject(xhttp.statueText);
        };
        xhttp.send()
    });
}
var promise = get("data/tweets.json);
promise.then(function(tweets) {
    console.log(tweets);
};
您试图做的是限制请求(即速率限制)。 这是一个有点高级的主题,一个简单的实现可以实现如下解决方案:

  • 每次创建请求时,您都会增加一些变量,当请求完成时(成功或失败),您会减少它(
    最终
  • 如果有超过限制的请求,则将其放入队列中,以便稍后处理
  • 定期(
    setInterval
    )检查队列的大小,如果队列为非空且传出请求少于5个,则从队列中取出一个项目并执行HTTP请求
  • 除了
    setInterval
    之外,您还可以在解析/拒绝一个请求时使用这种检查,然后使用
    setTimeout
    来安排检查(因为检查最近是否没有发生任何事情是没有意义的)

    var numberOfPendingRequests=0;
    var overLimitQueue=[];
    函数get(url){
    var getPromise=新承诺(函数(解析、拒绝){
    如果(numberOfPendingRequests>=5){
    超极限推送({
    url:url,
    决心:决心,,
    拒绝:拒绝
    });
    返回;
    }否则{
    numberOfPendingRequests++;
    ...
    }
    });
    getPromise.finally(函数(){
    未决请求数--;
    })
    回报承诺;
    }
    setInterval(函数(){
    如果(numberOfPendingRequests<5&&overLimitQueue.length>0){
    //处理队列中的条目
    }
    }, 1000);
    
    无论如何,这种代码相当高级,您最好使用其他人的库,而不是自己编写

    请查看此库,例如:


    执行请求的部分代码可以提取到较小的助手函数中,在用于重做调用或处理队列元素的代码中,您可以使用这些助手方法。您可能需要在helper方法调用之间传递
    resolve
    reject
    函数。

    这里有一种方法,不需要间隔计时器。它使用一个函数队列在下一个HTTP响应到达时调用(这使得挂起的请求数低于5):


    你有问题吗?对于Q+a站点来说有点必要是的,我的问题是如何在ES6中设置挂起的请求!!缩进代码是怎么回事?Hello@AmrAyoub,首先,请缩进您的代码以帮助其他人阅读,其次,您的问题实际上至少是两个问题:a)如何重试失败的HTTP请求,b)如何将传出请求的数量限制为5。不管怎样,你到底为什么要限制传出请求的数量?@hi Jakub,对不起,我不知道缩进代码是什么意思:(非常感谢,伙计,这正是我要找的:)谢谢,简单多了。
    var pending = 0;
    var queue = [];
    
    function get(url){
        return new Promise (function(resolve,reject){
            function loop(retries = 3) {
                var xhttp = new XMLHttpRequest();
                xhttp.open("GET",url,true);
                xhttp.onload = function(){
                    pending--;
                    if (xhttp.status == 200){
                        resolve(JSON.parse(xhttp.response));
                    }
                    else if (retries > 0) {
                        // retry by automatically relaunching the request:
                        loop(retries-1);
                    } else {
                        // give up
                        reject(xhttp.statusText); // correct your spelling!
                    }
                    if (pending < 5 && queue.length) {
                        // extract and execute the first of the queued actions:
                        queue.shift()();
                    }
                };
                xhttp.onerror= function(){
                    reject(xhttp.statusText); // correct your spelling
                };
                xhttp.send()
                pending++;
            }
            if (pending >= 5) {
                // Push the call we want to make for later execution in a queue:
                queue.push(loop);
            } else {
                loop(); // try at the most 3 times
            }
        });
    }