2013-07-18 47 views
0

在我的Rails應用程序中,使用jQuery滑塊。在滑塊停止事件中,有一個Ajax請求。如果用戶不斷滑動滑塊,則有太多未決的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)); 

我試着減少時間延遲。但沒有預期的結果。與上述情況相同。

+2

您是否考慮過首先減少請求?使用超時延遲請求,直到用戶停止滑動幾毫秒(例如300ms?)。 – nnnnnn

+2

要好得多才能發送請求,直到您檢測到它們停止滑動爲止。否則,控制檯將充滿中止警告。 –

回答

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; 
    }); 
} 
+0

對last_request進行了小改正,分配了$ .ajax。不工作,因爲它中止了Ajax請求,但機器進入掛起狀態。我沒有理解它。 – kd12

+0

是啊......剛剛在這裏試圖找到我自己的「非插件」解決方案,以類似的概率。必須注意,您是中止連接並重新連接的解決方案並非完全證明。我一直在使用'if($ ajax)$ ajax.abort();'鍵入多年的東西,並且已經注意到,有時我仍然以雙連接結束,但只有一個變量。無法找到其他連接存儲位置的我的生活,但它是我的變量分配到的那個的完全重複。真的需要找到一個解決方案,因爲這是在Chrome上吃掉了套接字... – SpYk3HH

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秒。

應該工作,但請注意,我還沒有測試過,所以如果你要嘗試它,請記住,這是一個普遍的想法,而不是一個精確的解決方案。

祝你好運。

0

正如評論中所說,最好不要發送請求,直到slideStop事件。通過這種方式,每次值被更改時都不會發送請求,因此服務器負載的問題更少。

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

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

    ajaxrequest(); 

});