Reputation: 21352
I have a Google Chrome extension that upon pressing a button executes an xmlhttp request to a server. I'm currently handling the error if the server is down. What I want to achieve is to retry the request after an increasing number of seconds. That's how I do it:
var execute = function(method, url, i){
//if timeout doesn't exist, create one
if(!i){
i = 1000;
}
var xmlhttp = new XMLHttpRequest();
xmlhttp.open(method, url, true);
xmlhttp.onreadystatechange = function(){
if (xmlhttp.status != 200) {
// Handle error, retry request
console.log("xmlhttp.status = " + xmlhttp.status + " and xmlhttp.readyState = " + xmlhttp.readyState);
setTimeout("execute('"+method+"', '"+url+"', "+i*2+")", i);
return;
}
};
xmlhttp.send(null);
}
Basically if there is some kind of problem I retry again the request. If the server is up, there is no problem at all, but if the server is down JavaScript throws me an error saying:
PUT http://localhost:3000/buy/2/id=1329664820124
executepopup.html:127
(anonymous function)
Which is not really meaningful, but however. The status in the log says "0", which is pretty lame too. If I turn on the server again while this is going on, it should stop doing this, but instead also if it succeeds (I see a log in the server that tells me that it received the request), it keeps calling the execute
method. I don't know how to stop this recursion if the server turns on. Am I doing something wrong? Is this state equal zero the problem?
Thanks a lot
Upvotes: 0
Views: 451
Reputation: 348982
onreadystatechange
is triggered for every state change, from state 0 to 4, and many times between. You should only be interested in readyState
4, because the request has fully finished at that point.
To get your method to work, check whether xmlhttp.readyState == 4
:
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status != 200) {
setTimeout("execute('"+method+"', '"+url+"', "+i*2+")", i);
is not the right way to call a function again. Since you're developing in a Chrome extension, you can use the following format for setTimeout
:
setTimeout(execute, i, method, url, i*2);
// Calls execute(method, url, i*2) after i milliseconds.
Upvotes: 4