在ajax调用中避免Race条件

时间:2016-07-05 15:58:42

标签: javascript jquery ajax

我有一个表单,它在提交按钮上返回数据日志。要显示我实现无限滚动的日志。只要滚动条到达页面底部,就会在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);
        }
    });
});

1 个答案:

答案 0 :(得分:2)

问题是因为在用户向下滚动时UI可以呈现的每个像素都会调用infinite_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,因为它使用起来非常糟糕。