如何停止所有活动或待处理的ajax请求?

时间:2013-07-18 14:07:01

标签: javascript jquery ruby-on-rails

在我的rails应用程序中,使用jquery滑块。在滑块的停止事件中,有一个ajax请求。如果用户连续滑动滑块,则有太多待处理的ajax请求,并且我的系统会挂起。我用过:

1:

function slide_stop(event, ui){
    $.xhrPool = [];
    $.xhrPool.abortAll = function() {
       $(this).each(function(idx, jqXHR) {
          jqXHR.abort();
       });
       $.xhrPool.length = 0
    };

    $.ajaxSetup({
      beforeSend: function(jqXHR) {
          $.xhrPool.push(jqXHR);
      },
      complete: function(jqXHR) {
         var index = $.xhrPool.indexOf(jqXHR);
         if (index > -1) {
            $.xhrPool.splice(index, 1);
         }
      }
   });
   $.xhrPool.abortAll();
   $('span#imgLoader').html('<img src="/assets/ajax-loader.gif">');
   $.ajax({
     type: 'get',
     dataType: 'json',
     url: 'some_url',
     data: { is_ajax: true }
   }).done(function(response){       
    $('span#imgLoader').empty();
   });
 }

 Initialize slider,
     $elt.slider({
        min:0,
        max:100,
        value:50,
        slide: slide_range,
        stop: slide_stop
    }).each(function(){
     add_range_label($range_elt);
    });

所有ajax请求都被停止/处于未修改状态。但是最后一个请求需要很长时间才能完成。没有结果再次挂起状态。

2:

var request = $.ajax(
{
    type: 'POST',
    url: 'someurl',
    success: function(result){}
});

然后,

request.abort();

不工作。太多请求仍处于暂挂状态。 我不知道它有什么问题。

我尝试使用'jquery-throttle-debounce'。包含的文件'jquery.ba-throttle-debounce.min.js' 应用jQuery.debounce来停止滑块事件。

$("#slider").on( "slidestop", $.debounce( 240, slide_stop ) );

我尝试减少时间延迟。但没有预期的结果。与上述情况相同。

3 个答案:

答案 0 :(得分:0)

尝试限制这些请求,因此对服务器的许多请求可能会导致服务器端出现性能问题,因为请记住每个ajax调用都是apache(或任何您的Web服务器)请求,这会占用内存和CPU。请记住,过多的请求可能会导致DDoS。

请记住,作为一个用户,我可以根据自己的喜好开始玩滑块,从而引发大量请求。

您应该添加以下内容:

var requests = [];
var lastCall = (+new Date()); // parenthesis just in case of minify
var timeDiff = 1000;

function sliderStopCallback() { // this will be called each time the slider stop sliding
     if(timeDiff < 400) {
         return;
     }

     abortAll();

     requests.push( $.ajax({
                             type: 'POST',
                             url: 'someurl',
                             success: function(result){}
               }) );
}

function sliderStartCallback() {  // this will be call each time the user start to slide
     timeDiff = (+new Date()) - lastCall;
     lastCall = (+new Date());
}

function abortAll() {
     var l = requests.length;
     while(l--) {
         requests[l].abort && requests[l].abort();  // the if is for the first case mostly, where array is still empty, so no abort method exists.
     }
}

这样,每个请求将在400毫秒内发送至少,防止每2秒进行一次呼叫。

应该有效,但请注意我没有测试过,所以如果您要尝试一下,请记住这是一个大致的想法,而不是一个精确的解决方案。

祝你好运。

答案 1 :(得分:0)

您可以使用http://archive.plugins.jquery.com/project/AjaxManager等插件。

此外,正如Javis所说,最好在发送响应之前加入延迟,这样您就不会因请求而不必要地重载服务器。我不会使用时差或数组,而只是保留对最后创建的ajax请求的引用。每次制作新请求时,您都会中止该请求。

// just putting these here for example, you would want to associate them with each instance of your slider control. 
var timeout, last_request; 

function slide_stop(event, ui){

   $('span#imgLoader').html('<img src="/assets/ajax-loader.gif">');
   // clear the timeout so a previous request won't be sent
   clearTimeout(timeout) 
   // set the request to be sent in .5 seconds
   timeout = setTimeout(send_request, 500); 
 }

function send_request(){
   // abort the last request if there is one
   if(last_request){
     last_request.abort();
   }
   last_request = $.ajax({
     type: 'get',
     dataType: 'json',
     url: 'some_url',
     data: { is_ajax: true }
   }).done(function(response){       
    $('span#imgLoader').empty();
    // set the last request to null so that you dont abort a completed request 
    //(this might not be necessary)
    last_request = null; 
   });
}

答案 2 :(得分:0)

正如评论中所述,最好不要在slideStop事件之前发送请求。这样,每次更改值时都不会发送请求,因此服务器负载不是问题。

function ajaxrequest(){
    $.ajax(....);
}

$("#slider").on("slideStop", function() {

    ajaxrequest();

});