20

I have an ajax call being made to a php file. I am receiving results. Now I am investigating if it is possible to have the ajax request automatically perform every 1 second. I am posting the results into input field called hidden. How can I execute the ajax call every three seconds without having to call the function?

    $.ajax({
            type: 'POST',
            url: 'increment.php',
            data: $(this).serialize(),
            dataType: 'json',
            success: function (data) {
                    $('#hidden').val(data);// first set the value     

            }
    });
Code_Ed_Student
  • 1,180
  • 6
  • 27
  • 67

3 Answers3

51

You can do this with a repeated series of setTimeout calls. (Don't use setInterval with ajax calls, you'll get chaos in no time; setInterval will fire off the next ajax call even if the previous one hasn't completed yet.)

Use setTimeout to schedule the first call, and then when it completes to schedule the next, etc.:

var interval = 1000;  // 1000 = 1 second, 3000 = 3 seconds
function doAjax() {
    $.ajax({
            type: 'POST',
            url: 'increment.php',
            data: $(this).serialize(),
            dataType: 'json',
            success: function (data) {
                    $('#hidden').val(data);// first set the value     
            },
            complete: function (data) {
                    // Schedule the next
                    setTimeout(doAjax, interval);
            }
    });
}
setTimeout(doAjax, interval);

Note that I'm using complete, not success, to schedule the next call, so that an interruption (temporary drop in your 'net connection, whatever) doesn't kill the process.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 2
    Now it makes more sense why to use `setTimeout` over `setInterval`. – Code_Ed_Student Dec 04 '13 at 09:48
  • Could you replace `complete` with `always` since the old one is now deprecated? – Dharman Dec 24 '20 at 21:31
  • 1
    @Dharman - You worried me for a second there, I thought "surely they can't have deprecated *that*?!" And [they haven't](https://api.jquery.com/jQuery.ajax/). The `complete` **option** (used above) is not deprecated. The `complete` *method* on the `jqXHR` object `ajax` returns (not used above) is deprecated. :-) – T.J. Crowder Dec 25 '20 at 09:45
16

Something you might want to consider is Server Sent Events (SSE's)

This is an HTML5 technology whereby Javascript will "long-poll" a server endpoint (your PHP file) to see if any changes have occurred. Long-polling is basically where JS (I'm not sure if it uses Ajax or another technology) sends a request every second to the endpoint

You can try it like this:

#/your_js
var evtSource = new EventSource("increment.php");
evtSource.onmessage = function(e) {
    $('#hidden').val(e.data);
}

To send the data, you can make an ajax call which will send the updated JSON object to the server, like you have:

  $(document).on("click", ".your_object", function(data) {
     $.ajax({
                type: 'POST',
                url: 'increment.php',
                data: $(this).serialize(),
                dataType: 'json'
        });
   });

This will only open an Ajax request when you perform an event, and your app will be "listening" for the response every second. As you are aware, Ajax long-polling is super resource-intensive, so it will be better to look at web-socket stuff if you want true "real-time" technology, but either way, this will be a much more efficient system than just using plain ajax for everything

A caveat here -- you'll have to change your increment.php to handle the different response types

Richard Peck
  • 76,116
  • 9
  • 93
  • 147
  • I can elaborate more if this is something you're interested in – Richard Peck Dec 04 '13 at 09:52
  • Very Nice, I was not aware of this. I keep checking the `increment.php` for the number of current rows in a table. I will read more into this – Code_Ed_Student Dec 04 '13 at 09:54
  • +1 interesting to have a HTML5 solution. – Praveen Dec 04 '13 at 09:54
  • I worked with SSE's when we were trying to create some real-time notifications in one of our apps. It felt like a mine-field at first, but it's actually quite simple to do, especially if you're using a framework. If not, it's still quite simple to deploy – Richard Peck Dec 04 '13 at 09:55
  • 1
    Very interesting, but it seems IE/Edge still doesn't support it as of [Can I use](http://caniuse.com/#feat=eventsource) – DaviG May 10 '17 at 16:03
7

Yes possible using setInterval

1) Keep your ajax within a function.

function fun() {
$.ajax({
            type: 'POST',
            url: 'increment.php',
            data: $(this).serialize(),
            dataType: 'json',
            success: function (data) {
                    $('#hidden').val(data);// first set the value     

            }
    });
}

2) Now using setInterval, you can execute it every second.

var interval = setInterval(fun, 1000);

3) To pause/clear use clearInterval

clearInterval(interval);

4) As other pointed that using setInterval for ajax is not wise, so try using

var interval;
function callAjax() {
  $.ajax({
                type: 'POST',
                url: 'increment.php',
                data: $(this).serialize(),
                dataType: 'json',
                success: function (data) {
                        $('#hidden').val(data);// first set the value 
                        interval = setTimeout(callAjax, 1000);   
                }
        });
}
callAjax();
//clearTimeout(interval);
Praveen
  • 55,303
  • 33
  • 133
  • 164
  • 2
    True, yet I'd prefer using `setTimeout` and `clearTimeout` so you don't get overlapping requests even though the server is a bit slow at executing the backend. – h2ooooooo Dec 04 '13 at 09:39
  • When using `ajax`, **definitely** use repeated `setTimeout` (schedule the next when the previous completes) rather than `setInterval`. With `setInterval` and ajax requests, you'll get chaos. – T.J. Crowder Dec 04 '13 at 09:40
  • 1
    Your `setTimeout` example results in a total of two calls to the function. – T.J. Crowder Dec 04 '13 at 09:50
  • @T.J.Crowder Sorry for that. I got the mistake I have done. I have corrected it. But +1 for letting us to know about `complete` callback. Very wise solution. Thank you. – Praveen Dec 04 '13 at 09:57
  • @PraveenJeganathan If you set `interval` inside the anonymous function, you might as well not set it. Either declare the variable in the global scope or don't bother declaring it at all. It's also `clearTimeout(interval)` and not `clearTimeout(fun)`. – h2ooooooo Dec 04 '13 at 10:04
  • @h2ooooooo Missed it. Thank you, for pointing my mistakes. – Praveen Dec 04 '13 at 10:12