MEH
MEH

Reputation: 41

Avoid Race condition in ajax call

I have a form which returns data logs on submit button.To display the logs I implemented infinite scroll. Whenever the scroll bar reaches the bottom of the page the next set of logs get loaded as an ajax call gets fired. However sometimes the logs do not appear in right order and sometimes multiple calls are triggered. How can I prevent that?

My code:

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

Upvotes: 0

Views: 727

Answers (1)

Rory McCrossan
Rory McCrossan

Reputation: 337550

The issue is because the infinite_scroll function gets called for every single pixel that the UI can render as the user scrolls down. That's potentially thousands of AJAX requests in a very short space of time, and all of them racing each other - as you've found.

A solution to this is to 'debounce' the scroll event so that the function is only called after scrolling has stopped. In your case this will ensure that an AJAX request is sent only on the last position of the scroll handle. This will stop the race condition and also dramatically reduce the load on your server. Try this:

var scrollTimer;

$(window).scroll(function () {
    clearTimeout(scrollTimer);
    scrollTimer = setTimeout(function() {
        if ($(window).scrollTop() + $(window).height() == $(document).height()) {
           infinite_scroll(data);
        }
    }, 200); // 200ms delay
});

You should also remove async: false from your AJAX request as it's incredibly bad practice to use.

Upvotes: 2

Related Questions