IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

[AJAX] Un conseil pour améliorer cette fonction d'appel générique ?


Sujet :

JavaScript

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de RomainVALERI
    Homme Profil pro
    POOête
    Inscrit en
    Avril 2008
    Messages
    2 652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : POOête

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 652
    Par défaut [AJAX] Un conseil pour améliorer cette fonction d'appel générique ?
    J'ai pas mal d'appels ajax dans l'application web que je développe actuellement, et comme la plupart d'entre eux (les plus simples en fait) ont la même structure, je me suis dit que j'allais faire une petite fonction... mais je perds tout l'avantage de l'asynchronicité ajax...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    // NE PAS UTILISER : problème à résoudre : perte de l'avantage de l'asynchronicité ajax 
    //( piste de résolution : gestionnaire d'événement pour récupérer la valeur de retour au lieu de l'attendre ) 
    // ---------------------------------------------------------
    // --- FONCTION APPEL AJAX STANDARD ---
    // --------------------------------------------------------- 
    // >>> réalise un appel ajax standard à partir des paramètres donnés :
    // PARAM #1 : URL de l'appel (chemin relatif à appeler par ajax, exemple :  "./repertoire/page.php"  ) 
    // PARAM #2 (optionnel) : chaine de paramètres au format "paramètres de requête" ( exemple : param1="bonjour"&param2="99548652"&param3="false" ) 
    // RETOUR : (string) de retour du traitement ajax ( ici ==> xhr.responseText ) 
    function appel_ajax_standard(url, params)
    {
    	window["retour"] = "";
    	var xhr = getXhr();
    	var ms = new Date().getTime();
    	params = (params)?(params + '&ms=' + ms):('ms=' + ms);
    	xhr.onreadystatechange = function()
    	{
    		if (xhr.readyState == 4)
    		{
    			if (xhr.status == 200)
    			{
    				// pas de return ici car il serait interprété comme étant le retour de la fonction "onreadystatechange"
    				window["retour"] = xhr.responseText;
    			}
    			else
    			{
    				window["retour"] = "Le serveur ne répond pas.";
    			}
    		}
    	}
    	xhr.open("GET", url + "?" + params, true);
    	xhr.send(null);
    	while (window["retour"] === "")
    	{ /* attente de la réponse */ }
    	return retour;
    }
    Je peux me débrouiller sans cette fonction, bien sûr, mais je me dis que je ne devais pas être loin... peut-être en définissant un événement personnalisé au retour de l'appel, que je récupèrerais avec un gestionnaire adapté...

    Si vous avez des suggestions... je suis preneur

    (détail à prendre en compte : je n'ai pas la liberté d'ajouter de nouveau framework à cette application, bien entendu, sinon j'aurais déjà collé du Prototype partout ^^)

    EDIT : corrections effectuées après commentaires de Bovino

  2. #2
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Billets dans le blog
    20
    Par défaut
    Quelques commentaires :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while (window["retour"] = "")
    Attention, c'est plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while (window["retour"] === "")
    Et cela présuppose que ta requête te renvoie effectivement quelquechose !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xhr.open("GET", ((params)?(url + "?" + params):url), true);
    Là encore attention, tu ne prends pas en compte les problèmes de mise en cache sur IE...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    var time_stamp = new Date();
    param = param?param + '&tt=' + time_stamp:'tt=' + time_stamp;
    xhr.open("GET", url + "?" + params, true);
    EDIT : Je ne saisi pas très bien l'intérêt de window["retour"] ?
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  3. #3
    Membre Expert
    Avatar de RomainVALERI
    Homme Profil pro
    POOête
    Inscrit en
    Avril 2008
    Messages
    2 652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : POOête

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 652
    Par défaut
    - en effet : pour le while, j'ai mis un "=" au lieu d'un "==" par inadvertance, mais pourquoi "===" ? (j'ai encore un peu de mal à appréhender cet opérateur de comparaison ... il teste à la fois la valeur ET le type de données c'est ça ?)

    - la fonction présuppose en effet que la requête me renvoie quelquechose, et j'aurais dû le rajouter dans l'en-tête de la fonction, c'est un des présupposés décidés au départ, ça me va très bien, jusque ici tous mes appels renvoient quelquechose (sauf dans le cas où mon xhr.status n'est pas à 200 mais ce cas est géré)

    - pour le timestamp en paramètre : au temps pour moi j'avais oublié de le rajouter

    - pourquoi utiliser window["retour"] plutôt que retour ?
    --> pour ne pas avoir de warning "variable non déclarée" (j'aime pas les warning ça me démange de les résoudre ^^)

    - pourquoi utiliser window["retour"] plutôt qu'un return xhr.responseText ?
    --> parce que le xhr.responseText n'est pas encore connu à la fin de l'execution de la fonction appel_ajax_standard ET parce que je ne peux pas non plus le placer dans la définition de la fonction onreadystatechange comme je l'ai expliqué en commentaire dans le code lui-même

    Merci beaucoup pour ta relecture ^^

  4. #4
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Billets dans le blog
    20
    Par défaut
    mais pourquoi "==="
    Par excès de zèle peut-être, mais "" est == à tellement de choses, que dans ce genre de cas je préfère en général le === (même si effectivement, cela agit sur la comparaison de types et que la requête Ajax ne te renvoie que du texte...)

    ET parce que je ne peux pas non plus le placer dans la définition de la fonction onreadystatechange comme je l'ai expliqué en commentaire dans le code lui-même
    Avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    xhr.onreadystatechange = return function()
    	{
    		if (xhr.readyState == 4)
    		{
    			if (xhr.status == 200)
    			{
    				return xhr.responseText;
    			}
    			else
    			{
    				return "Le serveur ne répond pas.";
    			}
    		}
    	}
    Tu gardes l'asynchronisme !
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  5. #5
    Membre Expert
    Avatar de RomainVALERI
    Homme Profil pro
    POOête
    Inscrit en
    Avril 2008
    Messages
    2 652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : POOête

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 652
    Par défaut
    Citation Envoyé par Bovino Voir le message
    Par excès de zèle peut-être, mais "" est == à tellement de choses, que dans ce genre de cas je préfère en général le === (même si effectivement, cela agit sur la comparaison de types et que la requête Ajax ne te renvoie que du texte...)
    Oui, je crois que tu as raison, dans le doute j'ai appliqué cette modif.
    Citation Envoyé par Bovino Voir le message
    Avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    xhr.onreadystatechange = return function()
    	{
    		if (xhr.readyState == 4)
    		{
    			if (xhr.status == 200)
    			{
    				return xhr.responseText;
    			}
    			else
    			{
    				return "Le serveur ne répond pas.";
    			}
    		}
    	}
    Tu gardes l'asynchronisme !
    Heu... non là je ne suis pas d'accord... (ou alors je n'ai pas compris ^^)
    Est-ce que ces deux return ne vont pas concerner la fonction onreadystatechange, ce qui fait que appel_ajax_standard ne renverrait rien...
    Citation Envoyé par marcha
    Mais bon, il serait plus judicieux comme tu l'as dit d'utiliser un évènement
    personnalisé. Il se trouve que le onreadystatechange est un évènement
    et que le plus simple est d'appeler une fonction depuis celui ci.
    Mais oui je n'y avais pas pensé du tout !
    Merci beaucoup, je trouve cette solution très bien, je vais la tester...

    Je suis toujours ouvert à des suggestions si vous voyez autre chose et bon dev' tout le monde.

  6. #6
    Membre Expert Avatar de DoubleU
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 106
    Par défaut
    Citation Envoyé par RomainVALERI
    Heu... non là je ne suis pas d'accord... (ou alors je n'ai pas compris ^^)
    Est-ce que ces deux return ne vont pas concerner la fonction onreadystatechange, ce qui fait que appel_ajax_standard ne renverrait rien...
    Tout à fait.

    Sinon, la solution que te propose marcha est la meilleure. C'est d'ailleurs sur ce principe que sont baties toutes les fonctions ajax dans les différents frameworks

  7. #7
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Par défaut
    Salut,

    Le problème avec ton code c'est que durant l'attente de la réponse du
    serveur, tu empêche toute autre opération sur ton interface.

    En fait tu "émule" le fonctionnement d'une requête synchrone avec une
    requête asynchrone. autan faire une requête synchrone dans ce cas.

    Mais bon, il serait plus judicieux comme tu l'as dit d'utiliser un évènement
    personnalisé. Il se trouve que le onreadystatechange est un évènement
    et que le plus simple est d'appeler une fonction depuis celui ci.

    Essaie de modifier ton code ainsi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    function appel_ajax_standard(url, params, onSuccess)
    {
    	var xhr = getXhr();
    	...
    	xhr.onreadystatechange = function()
    	{
    		if (xhr.readyState == 4)
    		{
    			if (xhr.status == 200)
    			{
    				onSuccess( xhr.responseText );
    			}
    		}
    	}
    	xhr.open("GET", url + "?" + params, true);
    	xhr.send(null);
    }
    ce qui va changer, c'est la manière d'utiliser ta fonction, au lieu
    d'un code du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    function clickQqPart() {
      var html = appel_ajax_standard('page.php', 'a=1');
      document.getElementById('output').innerHTML = html;
    }
    tu aurra un code du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    function clickQqPart() {
      appel_ajax_standard('page.php', 'a=1', function(html) {
        document.getElementById('output').innerHTML = html;
      });
    }
    Ce qui ne change pas grand chose au niveau de la quantité de code
    mais qui a l'avantage de permettre de faire autre chose avec ton
    interface durant les attentes sur le serveur.

Discussions similaires

  1. Conseil pour améliorer ce code
    Par Godzestla dans le forum Macros et VBA Excel
    Réponses: 7
    Dernier message: 07/11/2008, 13h46
  2. De l'aide pour améliorer cette unité très courte
    Par Bruno13 dans le forum Composants VCL
    Réponses: 6
    Dernier message: 30/06/2008, 21h22
  3. Réponses: 5
    Dernier message: 09/02/2008, 20h05
  4. Réponses: 2
    Dernier message: 30/01/2008, 10h35
  5. Conseils pour améliorer ma fonction
    Par Sergio29 dans le forum Windows Forms
    Réponses: 4
    Dernier message: 22/11/2007, 16h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo