tonga
tonga

Reputation: 11961

How to exit from this recursive polling from jQuery?

I previously asked about a question using Ajax polling from a server every 3 seconds using the following jQuery Ajax request:

function getData() {
    $.ajax({
        url : 'http://example.com',
        type: 'GET',
        success : function(data) {
            // process data here
            setTimeout(getData, 3000);
        },
        dataType : 'json'
    });
}

It seems that another way of doing this is putting setTimeout outside $.ajax() block:

function getData() {
    setTimeout( function() {
    $.ajax({
        url : 'http://example.com',
        type: 'GET',
        success : function(data) {
            //process data here
        },
        dataType : 'json'
    }) }, 3000);
}

So is there any difference between these two methods? Do they have the same effect of continuous polling the server every 3 seconds?

Also, inside the success callback function, how do I terminate this infinite polling if certain condition is met, say, data.length>1000 then I want to terminate this loop and call another function? Should I do something like this:

function getData() {
        var tID = setTimeout( function() {
        $.ajax({
            url : 'http://example.com',
            type: 'GET',
            success : function(data) {
                //process data here
                if(data.length > 1000) { 
                   funcOutside();
                   clearTimeout(tID);
                }
            },
            dataType : 'json'
        }) }, 3000);
    }

Upvotes: 3

Views: 4895

Answers (3)

Libu
Libu

Reputation: 213

(function loopsiloop(){
   setTimeout(function(){
   $.ajax({
       url: 'foo.htm',
       success: function( response ){
           // do something with the response

           loopsiloop(); // recurse
       },
       error: function(){
           // do some error handling.  you
           // should probably adjust the timeout
           // here.

           loopsiloop(); // recurse, if you'd like.
       }
   });
   }, 5000);
})();

This will do the work for you. I'm doing three things here:

  1. Declaring a function loopsiloop that is immediately invoked (notice the parens at the end).
  2. Declaring a timeout handler to fire after 5 seconds.
  3. Polling the server inside the timeout, which upon either success/failure will call loopsiloop and continue the poll.

Upvotes: 0

bfavaretto
bfavaretto

Reputation: 71908

So is there any difference between these two methods? Do they have the same effect of continuous polling the server every 3 seconds?

Yes, there is an important difference! The first version will queue a call to the function after the response arrives. So the interval between calls will be (roughly) 3000ms plus the time the request/response took.

The second version will make a request after 3 seconds, then stop. If you change setTimeout to setInterval, it would make a new request every 3 seconds, but there would be no guarantee the previous request will already have completed when a new one is made (if one request takes ~3000ms). So the first version is probably what you're looking for.

About terminating the loop: yes, just add a condition like the one you have in your code. But instead of clearing the timeout, just don't add a new one:

//process data here
if(data.length > 1000) { 
    funcOutside();
} else {
    setTimeout(getData, 3000);
}

Final note: technically, that's not recursion, because it's not getData calling itself, but the callback from setTimeout calling getData all the time.

Upvotes: 3

Jon
Jon

Reputation: 437356

The second option won't poll every 3 seconds; it will only poll just once.

To conditionally continue or stop polling you should use a variation of the first option: add a conditional around the setTimeout call.

function getData() {
    $.ajax({
        url : 'http://example.com',
        type: 'GET',
        success : function(data) {
            // depending on the data, either call setTimeout or simply don't
            if( /* data says continue polling */) {
                setTimeout(getData, 3000);
            }
        },
        dataType : 'json'
    });
}

Upvotes: 9

Related Questions