【问题标题】:jQuery request a list of url while limit the max number of concurrent request [duplicate]jQuery请求一个url列表,同时限制最大并发请求数[重复]
【发布时间】:2012-10-30 17:04:11
【问题描述】:

可能重复:
Queue AJAX calls

我有一个 id 列表:

var ids = [3738, 75995, 927, ... ]; // length is about 2000

我想用$.getJSON请求网址http://xx/ + id,比如:

ids.forEach(function(id, index){
    $.getJSON('http://xx/' + id, function(data){
        // store the data in another array.
    });
});

但是这样会一次性发出过多的请求,让浏览器阻塞一段时间,所以我的问题是,如何限制jQuery中的并发ajax请求数?例如,我发送了 10 个请求,当每个请求得到响应时,我发送另一个请求。

【问题讨论】:

  • 如果请求是异步传递的,它不会锁定浏览器。如果 $.getJSON 函数像 $.ajax 函数一样工作,那么所有调用都是异步的,你不必担心
  • @Bruno 太多异步请求也会导致浏览器崩溃
  • @Bruno 但我能感觉到浏览器显然很慢..
  • 我相信你必须每十次打破你的每个循环并跟踪你已经请求的时间,直到你做你必须做的一切。但由于我不知道这是否是一个好方法,我将把它作为评论留下
  • 解决办法应该是如何让后端处理多个id。

标签: javascript jquery ajax performance


【解决方案1】:

shift()pop() 在您启动请求时从数组中删除 id。首先发出 10 个请求。然后在您的 ajax 调用的 complete() 处理程序中,检查数组长度。如果大于 0,setTimeout 持续几百毫秒(以释放浏览器一点),然后移动或弹出另一个 ID 并触发另一个请求。

【讨论】:

    【解决方案2】:
    var $queue = $({});
    
    ids.forEach(function(id, index) {
        $queue.queue("ajaxQueue", function( next ) {
            $.getJSON('http://xx/' + id, function(data){
                // store the data in another array.
    
                next();
            });
        });
    });
    
    $queue.queue("ajaxQueue", function() {
        // everything is saved
    });
    
    $queue.dequeue("ajaxQueue");
    

    jQuery 文档:

    jQuery.queue
    jQuery.dequeue

    所以:

    What are queues in jQuery?


    还有:

    解决方案应该是如何让后端处理多个 id。 – epascarello


    ##当时的十个请求:有一些问题!

    var $queue = $({}),
        handler;
    
    ids.forEach(function(id, index) {
        if ( !(index % 10) && handler ) {
             $queue.queue("ajaxQueue", handler);
        }
        handler = (function(prev) {
            return function( next ) {
                prev();
                $.getJSON('http://xx/' + id, function(data){
                    // store the data in another array.
                });
                if ( next ) {
                    next();
                }
            }
        })(handler);
    });
    
    $queue.queue("ajaxQueue", function() {
        // everything is saved
    });
    
    $queue.dequeue("ajaxQueue");
    

    x % y

    (index % 10) => Math.floor(index/10)*10 === index;
    !(index % 10) => Math.floor(index/10)*10 !== index;
    

    【讨论】:

    • 谢谢,但这与在 jQuery 中将异步标志设置为 false 有何不同?
    • async:false 无法跨域工作并在发出请求时冻结整个应用程序。
    • @wong2 见评论。之前忘了[at]你。
    【解决方案3】:

    这应该可以解决问题:

    var current;    
    
    function fetchCurrentLast()
    {
        if (current < ids.length)
        {
            var id = ids[current];
            current++;
    
            $.getJSON('http://xx/' + id, function(data){
                // store the data in another array.
    
                fetchCurrentLast();
            });
        }
    }
    
    current = 0;
    
    for (var i = 0; i < 10; i++)
    {
        fetchCurrentLast();
    }
    

    【讨论】:

    • @mplungjan:是的,我们编写了相同的代码。至少,我认为这就是你所说的。如果不是,我不知道你在说什么。
    • 但是我是在callback函数中进行递归调用,也就是说只能在上一次调用完成后才能进行……
    • 但你不是!您快速调用该函数 10 次,然后每次调用一次,所以至少 20 次
    • 我一开始就叫它十次,这样我们就可以同时做 10 次,根据问题。由于(current &lt; ids.length) 检查,此代码适用于大小小于 20 的数组
    • 不。不服气。我要睡了。真正尝试您的代码
    【解决方案4】:
    var cnt = 0;
    function getEach() {
        if (cnt>=ids.length) return;
        $.getJSON('http://xx/' + ids[cnt], function(data){
        // store the data in another array.
        cnt++;
        getEach(); 
        // or setTimeout(getEach,1000); to wait a sec
        // or if (cnt%10==0) setTimeout(getEach,1000); to wait a sec every 10
        //    else getEach();
      });
    }
    

    【讨论】:

    • cnt++ 放错了地方,因为这段代码一次只能执行一个请求,而不是 10 个
    • 当前一个按照原始问题的要求完成时,这将一次完成所有请求
    • 来自问题:for example, I send 10 request and when each of them got the response I send another request.
    • MHmm 我没有注意到 2000,但我的代码在有或没有批处理的情况下都可以工作
    • 因为您仅在 ajax 请求返回后更新cnt,所以当您使用批处理时,您将多次获取相同的结果。例如,如果假设每个请求花费的时间甚至更长,那么您将得到 id = 0 的十倍结果,然后是 id=10 的十倍结果,依此类推(实际上它们不会花费同样长的时间,所以它变得很多更多的混乱)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-23
    • 2021-03-17
    • 1970-01-01
    相关资源
    最近更新 更多