Javascript 避免ajax调用中的竞争条件
我有一个表单,在提交按钮上返回数据日志。为了显示日志,我实现了无限滚动。每当滚动条到达页面底部时,就会加载下一组日志,因为会触发ajax调用。但是,有时日志的显示顺序不正确,有时会触发多个调用。我怎样才能防止呢 我的代码:Javascript 避免ajax调用中的竞争条件,javascript,jquery,ajax,Javascript,Jquery,Ajax,我有一个表单,在提交按钮上返回数据日志。为了显示日志,我实现了无限滚动。每当滚动条到达页面底部时,就会加载下一组日志,因为会触发ajax调用。但是,有时日志的显示顺序不正确,有时会触发多个调用。我怎样才能防止呢 我的代码: function infinite_scroll(data){ $.ajax({ url: '/api', dataType: 'json', data : data, type: 'GET', async: false, su
function infinite_scroll(data){
$.ajax({
url: '/api',
dataType: 'json',
data : data,
type: 'GET',
async: false,
success: function(response) {
$('#table_body').append(" some data ");
},
error: function( xhr, status ) {
alert( "Sorry, there was a problem! Please Try Again!" );
},
});
}
$(document).ready(function(){
$(window).scroll(function () {
if($(window).scrollTop() +$(window).height()==$(document).height()) {
infinite_scroll(data);
}
});
});
问题在于,当用户向下滚动时,用户界面可以呈现的每个像素都会调用
infinite\u scroll
函数。在很短的时间内,可能会有数千个AJAX请求,而且所有请求都在相互竞争——正如您所发现的那样
解决此问题的一个方法是“取消”滚动事件,以便仅在滚动停止后调用该函数。在您的情况下,这将确保仅在滚动句柄的最后一个位置发送AJAX请求。这将停止竞争状态,并显著降低服务器上的负载。试试这个:
var scrollTimer;
$(window).scroll(function () {
clearTimeout(scrollTimer);
scrollTimer = setTimeout(function() {
if ($(window).scrollTop() + $(window).height() == $(document).height()) {
infinite_scroll(data);
}
}, 200); // 200ms delay
});
您还应该从AJAX请求中删除
async:false
,因为使用它是非常糟糕的做法。问题在于,用户向下滚动时,UI可以呈现的每个像素都会调用infinite\u scroll
函数。在很短的时间内,可能会有数千个AJAX请求,而且所有请求都在相互竞争——正如您所发现的那样
解决此问题的一个方法是“取消”滚动事件,以便仅在滚动停止后调用该函数。在您的情况下,这将确保仅在滚动句柄的最后一个位置发送AJAX请求。这将停止竞争状态,并显著降低服务器上的负载。试试这个:
var scrollTimer;
$(window).scroll(function () {
clearTimeout(scrollTimer);
scrollTimer = setTimeout(function() {
if ($(window).scrollTop() + $(window).height() == $(document).height()) {
infinite_scroll(data);
}
}, 200); // 200ms delay
});
您还应该从AJAX请求中删除
async:false
,因为这是一种非常糟糕的做法。除了糟糕的做法之外async:false
也被浏览器弃用,现在会抛出警告console@charlietfl我更惊讶的是,在没有UI在placeMe上跳来跳去的情况下,滚动也能正常工作。他们会认为封锁会阻止进一步的scrolling@Rory,这可能是因为async:false
阻止请求实际并行运行。True,但是我可能已经通过了,在处理请求时,用户界面在滚动时会挂起。除了坏习惯之外,浏览器也不赞成使用async:false
,现在会抛出警告console@charlietfl我更惊讶的是,在没有UI在placeMe上跳来跳去的情况下,滚动也能正常工作。他们会认为封锁会阻止进一步的scrolling@Rory,这可能是因为async:false
阻止了请求实际并行运行。是的,但在处理请求时滚动时,UI会挂起。