Ajax Heartbeat using setInterval, Preventing multiple calls at the same time
Asked Answered
J

3

6

I wish to make an AJAX call using jQuery as a "heartbeat" in the background so that my web application can check for new data. For example every 10 seconds.

I have seen on other posts that it is possible to use setInterval() to call a method which does the call every X number of milliseconds.

However, what happens if my AJAX call takes more than 10 seconds? I still want it to complete the last request and I don't want another call to be instigated when there is already one in progress. This could result in the same information being placed on to the page twice!

What is the way to implement this for my method to wait for the original AJAX call to be completed, rather than simply "every 10 seconds", when the original one may not already be complete.

Jilli answered 6/12, 2012 at 17:29 Comment(1)
To anyone who's reading this I have just discovered WebSockets to implement this. If you're using ASP .NET already, then SignalR may be an ideal pairing as this uses Websockets and falls back automatically on to other technologies depending on the environment you're running. Socket.IO is another one.Jilli
P
11

try setting another timeout from your ajax success function:

function poll() {
    setTimeout( function() {
        $.ajax(.......).success( function(data) {
            poll();  //call your function again after successfully calling the first time.
        });
    }, 10000);
}
Pallor answered 6/12, 2012 at 17:34 Comment(2)
Thanks, I'll be implementing this!Jilli
Although the "success" method was deprecated in jQuery 3.0. Specifically, api.jquery.com/jQuery.ajax it says: Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are removed as of jQuery 3.0. You can use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.Surpass
S
6

Instead of using setInterval, call setTimeout() in the AJAX completion callback to start each call 10 seconds after the previous one finishes.

Stretch answered 6/12, 2012 at 17:31 Comment(0)
I
0

instead of using setInterval, calculate the request time (usually using a unix timestamp in seconds), how much for 10 seconds, in the server side, use setTimeout the remaining time, so it will vary from user to user, on their ping time (or the business of the site)

function heartbeat(){
  $.ajax({
    'url': '/where/',
    'success': function(data){
       setTimeout(heartbeat, parseInt(data) * 1000);
    }
  });
}
heartbeat(); // initialize it

in the server side, (like in PHP), you would do

<?php
// do your stuff
echo (time() - (int)$time_requested) + 10; // it will vary per user, so if it takes 2 second, it will be 12, if it returns imediately, returns 10 
Impatience answered 6/12, 2012 at 17:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.