/ / Délais d'attente sur les requêtes ajax périodiques avec jQuery - javascript, jquery

Délais d'attente sur les requêtes ajax périodiques avec jQuery - javascript, jquery

J'utilise le code suivant pour envoyer une requête ajax toutes les 3 secondes:

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);

Le problème est que même si le serveur domestique estnon accessible (par exemple, non connecté au réseau local), la fonction succès sera appelée à la place de la fonction d'erreur avec l'état "délai d'attente" (testé sur Ubuntu 10.04 avec FireFox 3.6.7).
(Sans requêtes périodiques, cela fonctionnera correctement: lors des dépassements de délai, la fonction d'erreur est appelée avec le correct "timeout" -statusText.)

La fonction alert-success affichera le texte suivant sur les délais d'attente:

textStatus: succès, XHR.readyState: 4, Statut XHR: 0
Donc, je dois utiliser la valeur XHR.status, qui devrait être 200 en cas de succès, pour déterminer les erreurs. Est-ce le comportement normal ou est-ce que quelque chose ne va pas?

Réponses:

3 pour la réponse № 1

réfléchissez plutôt au déplacement de setTimeout dans les gestionnaires de succès et d'erreur et rendez-le récursif de manière asynchrone.

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);
}
});
};

La chose est, setTimeout et setInterval le temps n'est pasfiable, surtout avec des alertes. Un appel d'alerte bloque le javascript tant que la boîte de dialogue d'alerte reste ouverte. De plus, setTimeout et setInterval n'interrompent pas le code en cours d'exécution pour garantir un timing parfait, ils attendent que le thread javascript ait une ouverture et passent d'une exécution à l'autre.

Avec votre configuration de code précédente, vous aviez également une chance que la réponse de l'appel rafraîchId 1 arrive après l'appel rafraîchId 2 en raison de l'aller-retour http prenant un laps de temps indéterminé.

En faisant dépendre votre setTimeout de la réponse, vous obtenez un résultat plus stable et transparent.


0 pour la réponse № 2

Eh bien, déconner avec les rappels de fonctions asyncrones peut devenir compliqué :). setInterval() en fait partie, .ajax().

Vous devriez essayer d'utiliser setTimeout() et juste tirer le prochain .ajax() appeler lorsque le dernier est terminé.

(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);
}
});
}());

Si vous insistez pour avoir un .ajax() aussi près que possible de 3 secondes, vous pouvez abandonner votre dernière requête ajax (éventuellement en cours d'exécution) avant de lancer la nouvelle.

Par conséquent, affectez une variable au retour de .ajax() comme

var currentxhr = $.ajax({});

et ajouter un beforeSend rappel dans votre .ajax() appel. Dans cet appel de gestionnaire

currentxhr.abort();

Cela annulera une requête en cours d'exécution.


0 pour la réponse № 3

Au lieu de regarder textStatus utilisez ce test: xhr.statusText.toUpperCase() === "OK"

Je suis tombé sur un problème avec FF 3.6.8 ayant un xhr.status === 0 sur 301 pages. J'ai ajouté ce qui précède à ma jQuery 1.4.2 dans le httpSuccess fonction:

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 pour la réponse № 4

Je crois que vous devriez http://plugins.jquery.com/project/ajaxqueue qui est conçu pour gérer les conditions de course ajax.