Timeouts for periodic ajax requests using jQuery

I use the following code to send an ajax request every 3 seconds:

var refreshId = setInterval(function() { $.ajax({ async: true, url: 'gohere', dataType: 'text', cache: false, timeout: 5000, success: function(result, textStatus, XMLHttpRequest) { alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status); }, error: function(XMLHttpRequest, textStatus, errorThrown) { alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status); } }); }, 3000); 

The problem is that even if the home server is unavailable (for example, not connected to the local network), instead of the error function with the timeout function, the success function will be called (tested on Ubuntu 10.04 with FireFox 3.6.7).
(Without periodic requests, it will work fine: with timeouts, the error function is called with the correct "timeout" -statusText.)

The alert-function will display the following text at timeouts:

  textStatus: success,
     XHR.readyState: 4,
     XHR.status: 0
Therefore, I need to use the XHR.status value, which must be 200 on success, to identify errors. Is this normal behavior or is something wrong?
+4
source share
4 answers

Consider moving setTimeout to success and error handlers and making it asynchronously recursive.

 var refreshId = function() { $.ajax({ async: true, url: 'gohere', dataType: 'text', cache: false, timeout: 5000, success: function(result, textStatus, XMLHttpRequest) { alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status); setTimeout(refreshId, 3000); }, error: function(XMLHttpRequest, textStatus, errorThrown) { alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status); setTimeout(refreshId, 3000); } }); }; 

Thing is, setTimeout and setInterval time is not reliable, especially with warnings. A warning call stops javascript while the warning dialog remains open. In addition, setTimeout and setInterval do not interrupt the current code to guarantee the perfect timing; they will wait until the javascript stream opens and is affected between code execution.

With your previous code setup, you also had a chance that the refreshId response would call 1, come after refreshId call 2 because http roundtrip takes an indefinite amount of time.

Due to the fact that your setTimeout depends on the incoming response, you get a more stable and transparent result.

+3
source

Well, messing around with asynchronous function callbacks can become messy :). setInterval() is one of them, therefore .ajax() .

You should try using setTimeout() and just run the next .ajax() call when the last one has completed.

 (function repeat(){ $.ajax({ async: true, url: 'gohere', dataType: 'text', cache: false, timeout: 5000, success: function(result, textStatus, XMLHttpRequest) { alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status); }, error: function(XMLHttpRequest, textStatus, errorThrown) { alert('textStatus: ' + textStatus + ",\nXHR.readyState: " + XMLHttpRequest.readyState + ",\nXHT.status: " + XMLHttpRequest.status); }, complete: function(XMLHttpRequest){ setTimeout(repeat, 3000); } }); }()); 

If you insist that .ajax() be as close as possible to 3 seconds, you can interrupt your last (possibly launched) ajax request before starting a new one.

Therefore, assign the .ajax() return variable as

 var currentxhr = $.ajax({}); 

and add the beforeSend to your .ajax() call. Within this call handler

 currentxhr.abort(); 

This will result in the cancellation of a possibly running request.

0
source

Instead of searching for textStatus use this test: xhr.statusText.toUpperCase() === 'OK'

I had a problem with FF 3.6.8 with xhr.status === 0 on 301 page. I added this to my jQuery 1.4.2 in the httpSuccess function:

 return !xhr.status && location.protocol === "file:" || // Opera returns 0 when status is 304 ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 304 || xhr.status === 1223 || ( xhr.status === 0 && xhr.statusText.toUpperCase() === 'OK'); 
0
source

I believe that you should study the http://plugins.jquery.com/project/ajaxqueue , which is designed to control the conditions of the ajax race.

0
source

All Articles