0

在我的 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 ) );

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

4

3 回答 3

0

尝试限制这些请求,对服务器的如此多的请求可能会导致服务器端出现性能问题,因为请记住每个 ajax 调用都是一个 apache(或任何您的网络服务器)请求,这会消耗内存和 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 秒调用一次。

应该可行,但请注意我还没有测试过,所以如果你要尝试它,请记住这是一个普遍的想法,而不是一个精确的解决方案。

祝你好运。

于 2013-07-18T14:34:07.360 回答
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; 
   });
}
于 2013-07-18T14:47:40.827 回答
0

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

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

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

    ajaxrequest();

});
于 2016-03-11T11:41:17.873 回答