在我的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 ) );
我尝试减少时间延迟。但没有预期的结果。与上述情况相同。
答案 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();
});