在总共n次调用中一次执行5次ajax调用

时间:2017-08-31 05:37:52

标签: jquery ajax

我目前有一个从最初的ajax调用中得到的id数组,我需要进行后续调用。假设该阵列中有20个ID。

我现在需要做的是一次只进行5次调用,因为我们不想超载我们的服务器。一旦这5个完成,就开始下一个5.一旦完成,我需要console.log('done');

var ids = [3,5,2,6,7,13,35,27,8,5,3,5,26,57,18,3,42,67];
var results = {};

var ajaxCall = function(id) {
    $.ajax({ 
       url: '/url?id=' + id, method: 'GET'})
      .complete(function(data) {
           results[id] = data;
      });
}

4 个答案:

答案 0 :(得分:1)

您需要使用setInterval来检查每个5 AJAX调用以及最后一组5条记录clearInterval,如下面的代码。

请检查以下示例,了解在处理完每个5 Ajax callconsole.log('completed');后如何设置{。}}。

function make5call()

以上功能只会从next 5

请求array ID
function initTimer()

以上计时器将检查所有5 Ajax request是否已完成,然后开始下一个set of 5 request,如果全部完成,则clearInterval

var ids = [3, 5, 2, 6, 7, 13, 35, 27, 8, 5, 3, 5, 26, 57, 18, 3, 42, 67];
//var ids = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19];

var results = {};
var length = ids.length;
var j = 0;
var pendingAJAX = 5; // Set of ajax call in one go
var complete = false;
var totalCompleted = 0;

// Ajax request function
var ajaxCall = function(id) {
  $.ajax({
      url: '/url?id' + id,
      method: 'GET'
    })
    .complete(function(data) {
      results[id] = data;
      console.log(id);
      pendingAJAX--; //After each complete decrement one
      totalCompleted++; //Track for completed Ajax
      // If all sets are completed and total is also same as your ids
      if (complete && totalCompleted == ids.length) {
        console.log('completed');
      }
    });
}

var make5call = function() {

  for (var i = 0; i < 5; i++) {
    // If all Ajax finished set complete to true
    if (j == ids.length) {
      complete = true;
    }
    if (j < ids.length) {
      ajaxCall(ids[j]); //request Ajax
      j++;
    }
  }
}

// Timer to check when to call for next 5 request
var initTimer = function() {

  var timer = null;
  timer = window.setInterval(function() {

    // Either all are completed or 5 Ajax complted clear interval
    if (pendingAJAX == 0 || complete) {
      timer = window.clearInterval(timer);
      timer = null;
      // If All are not finished yet start timer again
      if (!complete) {
        pendingAJAX = 5;
        initTimer();
        make5call();
      }
    }
  }, 100);

}

initTimer();
make5call();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

答案 1 :(得分:0)

一次的5次呼叫将很难;)但是你可以按顺序进行5次呼叫,等待一秒钟(这可以防止洪水进入服务器)。

这5个电话应与async: false一起发送,因此您要将这些(ajax)电话设为同步

如果您希望异步,则难以管理等待效果。因为这一切都取决于处理呼叫的速度。它会起作用,但你应该等待更长时间才能产生效果。

我会使用余数函数。

var ids = [3, 5, 2, 6, 7, 13, 35, 27, 8, 5, 3, 5, 26, 57, 18, 3, 42, 67];

for (i = 0; i < ids.length; i++) {
  // one ore more ajax calls
  if (i % 5 == 0) {
    // pause
    console.log("do something else 5 calls, i=" + i);
  }
}

https://jsfiddle.net/wx9o01e3/2/

答案 2 :(得分:0)

绝对没有理由使用等待,同步ajax或间隔...这里的策略是手动启动5 ajax,并在完成后启动另一个ajax。这样你就可以同时拥有5个ajax,并且不必等待其中的5个完成,然后再解雇5个。

var ids = [3,5,2,6,7,13,35,27,8,5,3,5,26,57,18,3,42,67];
var results = {};

var ajaxCall = function(id) {
    $.ajax({url: '/url?id=' + id, method: 'GET'})
      .done(function(data) {
           results[id] = data;
           newAjaxCall();
      }).fail(function(){
           //handle failure if needed.
           //Do not prevent other calls to run so start a new one.
           newAjaxCall();
      });
}
var newAjaxCall = function(){
    if(ids.length>0){
        ajaxCall(ids.shift());
    }
}
//Start the ajax chain;
var ajaxAmount = 5;
for(var i=0;i<ajaxAmount;i++){
    newAjaxCall();
}

因此,我们所做的是我们有一个函数,它将使用数组的下一个ID创建新的ajaxCall,删除该ID,以便不重用它。如果数组需要保持完整,克隆可以执行或保持下一个ID的索引可以工作。我已将.complete更改为.done,因为它已在jQuery 3中弃用。

一旦我们完成了所有设置,我们就会创建我们想要的ajax调用量。

编辑:在重新阅读OP之后,似乎你真的想等待5个ajax调用结束,然后再启动5个其他调用。虽然我确实理解为什么你想在一个给定的时间只处理5个,但是我不明白为什么这些5在继续之前完成...这是修改后的代码来实现它:

var ids = [3,5,2,6,7,13,35,27,8,5,3,5,26,57,18,3,42,67];
var results = {};

var ajaxCall = function(id) {
    return $.ajax({url: '/url?id=' + id, method: 'GET'})
      .done(function(data) {
           results[id] = data;
      }).fail(function(){
           //handle failure if needed.
      });
}
var ajaxChain = function(){
    var ajaxAmount = 5;
    var ongoingCalls = 0;

    for(var i=0;i<ajaxAmount;i++){
        if(ids.length>0){
            onGoingCalls++;
            ajaxCall(ids.shift()).always(function(){
                ongoingCalls--;
                if(ongoingCalls == 0){
                    ajaxChain();
                }
            });
        }
    }
}
//Start the ajax chain;
ajaxChain();

答案 3 :(得分:0)

首先为ajax调用创建一个池。

var ajaxPool = function(length) {
    this.length = length;
    this.ajaxRequests = [];
        this.callbacks = [];
}
$.extend(ajaxPool.prototype, {
    add: function(options) {
        this.ajaxRequests.push({
            options: options
        });
    },
    success: function(callback) {
        this.callbacks.push(callback);
            return this;
    },
    triggerCallback:function(){
        var xthis = this;
        this.callbacks.forEach(function(callback){
        callback.call(this);
      });       
    },
    executeNext: function() {
        var xthis = this;
        var i = 0;
        for ( ;i < this.ajaxRequests.length; i++) {
            if (!this.ajaxRequests[i].executed) {
                                console.log('executing '+i+' request');
                $.ajax(this.ajaxRequests[i].options).complete(function() {
                    xthis.executeNext();
                });
                this.ajaxRequests[i].executed = true;
                break;
            }
        }
        if(i==this.ajaxRequests.length && !this.complete){
            this.complete = true;
            this.triggerCallback();
        }
    },
    executeAll: function() {
        if (this.length > this.ajaxRequests.length) {
            this.length = this.ajaxRequests.length;
        }
        var xthis = this;
        for (var i = 0; i < this.length; i++) {
                        console.log('executing '+i+' request')
            $.ajax(this.ajaxRequests[i].options).complete(function() {
                xthis.executeNext();
            });
            this.ajaxRequests[i].executed = true;
        }
    }
})

然后将您的参数添加到此池并开始以块的形式执行请求

var ids = [3,5,2,6,7,13,35,27,8,5,3,5,26,57,18,3,42,67];
var pool = new ajaxPool(5);
//adding a success function when all are completed
pool.success(function(){
    console.log('All Done!!!');
});
var results = {};
ids.forEach(function(id){
    pool.add({ 
       url: '/url?id=' + id, method: 'GET',success:function(data) {
           results[id] = data;
      }})

})
pool.executeAll();

工作示例

https://jsfiddle.net/memsv4fk/