cs_AlexN
Messages postés694Date d'inscriptionlundi 5 décembre 2005StatutMembreDernière intervention 8 janvier 2014
-
26 sept. 2007 à 15:37
cs_mlwacosmos
Messages postés1Date d'inscriptionvendredi 29 juin 2007StatutMembreDernière intervention27 novembre 2008
-
27 nov. 2008 à 16:26
Bonjour,
Je cherche à synchroniser une requete ajax asynchrone. Et je prend une grosse suée.
Je fais appel de manière cyclique à une requete ajax en mode asynchrone.
mode cyclique parce que je relance la requete tant que la reponse ne contient pas ce qu'il faut.
mode asynchrone parce que c'est le seul mode ou abort est utilisable (et ou ça ne bloque pas le navigateur pendant les requetes)
Mais ! il faut aussi que je puisse stopper (abort) la requete si la réponse ne vient pas au bout d'un certain temps (timeout du cycle des requetes).
Je cherche à avoir une fonction du genre
while(!ready) {
getDom(url);
}
où getDom(url) lance un cycle de requete ajax jusqu'à obtention de la reponse voulue ou que le timeout soit ecoulé.
De sorte que l'execution boucle (d'ou l'idee de synchroniser) sur ce getDom sans bloquer le reste. Suis-je clair ?
pour avoir une petite idée du contexte :
<html>
<head>
<title>is my datas ready ?</title>
</head>
stop <script type="text/javascript">
/* XMLHttpRequest */
var xhr = false;
var url = "test.xml";
var ie = false;
// branch for native XMLHttpRequest object
if(window.XMLHttpRequest && !(window.ActiveXObject)) {
try {
xhr = new XMLHttpRequest();
} catch(e) {
xhr = false;
}
// branch for IE/Windows ActiveX version
} else if (window.ActiveXObject) {
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
ie = true;
} catch(e) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
ie = true;
} catch(e) {
xhr = false;
}
}
}
function get () {
if (xhr) {
xhr.open("GET", url, true);
xhr.send("");
}
}
function abort() {
xhr.abort();
document.getElementById("z1").value='aborted';
}
xhr.onreadystatechange = getContents;
var debut = new Date();
get();
fini = false;
function f() {
var now = new Date();
document.getElementById("x1").value = now;
var elapsed = now.getTime() - debut.getTime();
document.getElementById("y1").value = elapsed;
fini = elapsed > 5000;
if (fini) abort();
else setTimeout("f()", 100);
}
f();
</script>
</html>
le xml (en fait la il n'y a pas ok mais not ok mais un jour il y aura ok a la place):
cs_bultez
Messages postés13615Date d'inscriptionjeudi 13 février 2003StatutMembreDernière intervention15 octobre 201330 27 sept. 2007 à 11:58
Bonjour,
je n'ai probablement pas compris ton problème...
setTimeout("get();", 1000); est fait sytématiquement,
ne le faire que si la réponse n'est pas ="ok" et si le délai
imparti pour cette réponse n'est pas atteint,
sinon, déclencher une "fonction de fin".
cs_AlexN
Messages postés694Date d'inscriptionlundi 5 décembre 2005StatutMembreDernière intervention 8 janvier 201419 27 sept. 2007 à 13:18
Merci pour ta suggestion bultez mais ce n'est pas ça.
En fait oui pour l'instant le setTimeout("get()", 1000); est fait systématiquement parce que c'est juste un code de test. Ce qui me précocupait ce n'était pas le contenu de la réponse. Le titre de ma question n'est pas clair non plus.
Un titre plus explicite serait plutôt : "Comment resynchroniser une requete ajax asynchrone"
et la fonction f() devrait s'appeler quelquechose comme check().
Pour l'instant ce que fait ce code :
- il lance à intervalle régulier une requete ajax, et ce seulement quand la précédente est terminée (et il devrait aussi y avoir la condition sur "calcul fini" comme tu le fais remarquer)
- il lance "en parallèle" un compteur qui vérifie que le temps imparti n'est pas dépassé, et si celui est dépassé il stoppe la requete en cours.
Mais il ne permet pas de faire boucler temporairement l'execution sur cette portion de code
Je vais essayer d'expliquer mon problème. Je dois mettre en place un mécanisme qui :
- lance une requete ajax à intervalle régulier pour connaitre l'état d'avancement d'un calcul
- stoppe cette série de requête
- soit lorsque la réponse contient un code disant "calcul fini"
- soit lorsqu'un temps donné pour le cycle de requête est dépassé
- provoque un "blocage" (pas un arrêt complet mais plutôt une boucle d'attente) sur ce mécanisme (le reste du javascript ne peut pas être exécuté tant que la réponse "calcul fini" n'est pas arrivée ou que le delai d'attente de ce calcul n'est pas dépassé.
Le seul moyen pour l'instant de stopper une requete ajax est de la mettre en asynchrone.
Mais d'un autre coté, comme elle est asynchrone, le xhr.send devient non bloquant. Et la boucle d'attente n'est pas bloquante non plus.
En fouillant à droite à gauche je n'ai pas trouvé grand chose d'autre que "ca n'a pas l'air possible" à part avec des composants php (sajax) ou java (htmlunit), ce que je ne peux pas utiliser parce tout doit être réalisé du coté client.
En fait, après réflexion il semble que ce ne soit pas possible du tout. Je suis parti dans une autre direction qui serait de simuler le while par un système de timeline. Mais c'est pas gagné non plus.
Voici l'état du code quand j'ai dit stop, faut arreter :
function get(url) {
//try {
if (xhr) {
xhr.open("GET", url, true);
xhr.send("");
}
//} catch (e) {}
}
function abort() {
if (xhr) {
xhr.abort();
document.getElementById("message").value = 'aborted';
}
if (checkTimer) clearTimeout(checkTimer);
if (getTimer) clearTimeout(getTimer);
}
function check() {
var now = new Date();
document.getElementById("x1").value = now;
var elapsed = now.getTime() - start.getTime();
document.getElementById("y1").value = elapsed;
timeover = elapsed > 5000;
if (timeover) abort();
else checkTimer = setTimeout("check()", 100);
}
cs_mlwacosmos
Messages postés1Date d'inscriptionvendredi 29 juin 2007StatutMembreDernière intervention27 novembre 2008 27 nov. 2008 à 16:26
Bonjour,
La question est ancienne mais je peux fournir une réponse et ça peut toujours aider.
Pour les puristes une requête ajax est forcément asynchrone et il est interdit de lancer des requêtes synchrones si bien qu'un navigateur comme firefox ne l'accepte pas facilement.
Néanmoins c'est possible en changer le paramètre true en false.
Sous ie pas de soucis, mais sous firefox il faudra recopier apres le request.send les différentes bifurcations que l'on fait habituellement quand on reçoit la réponse du serveur.
Un petit exemple pour firefox? ok
request.onreadystatechange = function () {
if(request.readyState == 4) {
if(request.status == 200) {
//ce que je fais
}
}
}
request.send(null);
if(not ie et requete est synchrone(à savoir false pour le paramètre) {
//ce que je fais
}
Le problème avec firefox c'est que l'on ne vérifie pas le code de retour du serveur.