Javascript 避免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

我有一个表单,在提交按钮上返回数据日志。为了显示日志,我实现了无限滚动。每当滚动条到达页面底部时,就会加载下一组日志,因为会触发ajax调用。但是,有时日志的显示顺序不正确,有时会触发多个调用。我怎样才能防止呢

我的代码:

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会挂起。