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

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

    Informations professionnelles :
    Activité : POOête

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 652
    Points : 4 164
    Points
    4 164
    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

    ...pour les linguistes et les curieux >>> générateur de phrases aléatoires

    __________________

  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 : 53
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 418
    Points
    91 418
    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
    Expert confirmé
    Avatar de RomainVALERI
    Homme Profil pro
    POOête
    Inscrit en
    Avril 2008
    Messages
    2 652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : POOête

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 652
    Points : 4 164
    Points
    4 164
    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 ^^

    ...pour les linguistes et les curieux >>> générateur de phrases aléatoires

    __________________

  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 : 53
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 418
    Points
    91 418
    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
    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 : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Points : 2 351
    Points
    2 351
    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.
    Si ton code fait plus d'une ligne, c'est que tu as mal choisi ton langage !

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

    Informations professionnelles :
    Activité : POOête

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 652
    Points : 4 164
    Points
    4 164
    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.

    ...pour les linguistes et les curieux >>> générateur de phrases aléatoires

    __________________

  7. #7
    Membre expérimenté 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
    Points : 1 388
    Points
    1 388
    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

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

    Informations professionnelles :
    Activité : POOête

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 652
    Points : 4 164
    Points
    4 164
    Par défaut état après vos améliorations
    Maintenant qu'elle est fonctionnelle, si quiconque en a besoin... ^^ (sait-on jamais ? quelqu'un qui n'aurait pas la liberté d'utiliser de framework évolué ?)
    Code javascript : 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
    38
    39
     
    // ---------------------------------------------------------
    // --- FONCTION APPEL AJAX STANDARD ---
    // --------------------------------------------------------- 
    // >>> réalise un appel ajax standard à partir des paramètres donnés :
    // PARAM #1 : ( fonction anonyme ) pour le traitement du retour, par exemple : function(retour) { alert(retour); } 
    // PARAM #2 : ( chaine ) URL de l'appel (chemin relatif à appeler par ajax, exemple :  "./repertoire/page.php"  ) 
    // PARAM #3 ( chaine ) ( optionnel ) : les paramètres au format "paramètres de requête" ( exemple : param1="bonjour"&param2="99548652"&param3="false" ) 
    // RETOUR : ( booléen ) informant sur le succès/échec de l'appel
    function appel_ajax_standard(onSuccess, url, params)
    {
    	var ms = new Date().getTime();
    	params = (params)?(params + '&ms=' + ms):('ms=' + ms);
    	try
    	{
    		var xhr = getXhr();
    		xhr.onreadystatechange = function()
    		{
    			if (xhr.readyState == 4)
    			{
    				if (xhr.status == 200)
    				{
    					onSuccess(xhr.responseText);
    				}
    				else
    				{
    					onSuccess("Erreur : Le serveur ne répond pas.");
    				}
    			}
    		}
    		xhr.open("GET", (url + "?" + params), true);
    		xhr.send(null);
    		return true;
    	}
    	catch (e)
    	{
    		return false;
    	}
    } // merci à Bovino et marcha ;-)

    edit : après la remarque de Bovino pour le xhr.open

    ...pour les linguistes et les curieux >>> générateur de phrases aléatoires

    __________________

  9. #9
    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 : 53
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 418
    Points
    91 418
    Billets dans le blog
    20
    Par défaut
    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...
    Attention, les deux return :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    if (xhr.readyState == 4){
    	if (xhr.status == 200){
    		return xhr.responseText;
    	}
    	else{
    		return "Le serveur ne répond pas.";
    	}
    }
    vont effectivement concerner la fonction onreadystatechange, en revanche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xhr.onreadystatechange = return function(){...}
    Renverra bien le résultat du traitement de cette fonction à la fonction appelante.
    En revanche, la solution de Marcha est effectivement bien meilleure... La mienne te renvoyant une réponse à chaque changement du readyState.
    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

  10. #10
    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 : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Points : 2 351
    Points
    2 351
    Par défaut
    Je te propose de mettre le paramètre onSuccess en dernier plutôt qu'en
    premier.

    et de modifier ton code ainsi:

    if(onSuccess) onSuccess(...);

    Ceci permet de rendre ce paramètre optionnel, il existe des cas où l'on
    fait une requête serveur sans tenir compte de la réponse.

    Sinon une approche que les framework utilisent et qui est fort pratique
    c'est de passer un objet dans un paramètre options.

    options.onSuccess, options.onFailure etc...
    Si ton code fait plus d'une ligne, c'est que tu as mal choisi ton langage !

  11. #11
    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 : 53
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Points : 91 418
    Points
    91 418
    Billets dans le blog
    20
    Par défaut
    Tu peux aussi supprimer le test sur cette ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xhr.open("GET", ((params)?(url + "?" + params):url), true);
    puisque tu as désormais obligatoirement une variable param.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xhr.open("GET", url + "?" + params, true);
    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

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

    Informations professionnelles :
    Activité : POOête

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 652
    Points : 4 164
    Points
    4 164
    Par défaut
    @Bovino : c'est vrai, ce test n'est plus utile, mais je l'ai effectivement déjà remplacé après ton conseil sur l'oubli du timestamp (edit : remplacé chez moi mais pas dans le code de ce thread... ^^ c'est fait maintenant)

    @marcha : pour l'optionnalité (pas sûr que cette substantivation soit correcte mais je suis sûr que vous me comprenez ^^) du param onSuccess, ça me semble être plus que judicieux
    ---> je prends
    Par contre, je crois que je vais aussi modifier mon xhr.open pour ne faire un appel asynchrone que si j'attends une réponse, avec :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    xhr.open("GET", url + "?" + params, (onSuccess !== "undefined"));
    Pour l'objet passé en paramètre contenant les diverses fonctions de traitement, ça serait une manière bien meilleure de gérer les différents cas de figure, oui ^^
    J'avais au départ écrit cette fonction pour gérer les cas "standard", en laissant les appels plus sophistiqués gérés par des fonctions complètes et personnalisées, mais c'est vrai que grâce à vos divers conseils, on en arrive à une fonction qui pourrait probablement remplacer même mes appels plus complexes... j'y fonce

    ...pour les linguistes et les curieux >>> générateur de phrases aléatoires

    __________________

  13. #13
    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 : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Points : 2 351
    Points
    2 351
    Par défaut
    Faire dépendre le mode synchrone de la requête avec la présence du paramètre onSuccess me semble pas judicieux.
    Si ton code fait plus d'une ligne, c'est que tu as mal choisi ton langage !

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

    Informations professionnelles :
    Activité : POOête

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 652
    Points : 4 164
    Points
    4 164
    Par défaut
    Citation Envoyé par marcha Voir le message
    Faire dépendre le mode synchrone de la requête avec la présence du paramètre onSuccess me semble pas judicieux.
    Hum... j'y réfléchissais et effectivement je ne suis plus si convaincu Même si on n'attend pas de réponse du serveur, les traitements clients ne doivent pas être figés... oublions ^^

    Je me suis dit par contre que le test de l'existence de la fonction onSuccess pouvait aussi bien être mis en facteur car on n'a pas besoin de différencier le xhr.status si on n'attend pas de réponse de toute façon...

    On aurait alors pour le moment ceci : (avec un exemple d'appel à la fin)
    Code javascript : 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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    // ---------------------------------------------------------
    // --- FONCTION APPEL AJAX STANDARD ---
    // --------------------------------------------------------- 
    // >>> réalise un appel ajax standard à partir des paramètres donnés :
    // PARAM #1 : ( chaine ) URL de l'appel (chemin relatif à appeler par ajax, exemple :  "./repertoire/page.php"  ) 
    // PARAM #2 ( chaine ) ( optionnelle ) : les paramètres au format "paramètres de requête" ( exemple : param1="bonjour"&param2="99548652"&param3="false" ) 
    // PARAM #3 : ( fonction anonyme ) ( optionnelle ) pour le traitement du retour, avec deux arguments, par exemple : function(succes, retour) { if ( succes ) alert(retour); } 
    // RETOUR : ( booléen ) informant sur le succès/échec de l'appel
    function appel_ajax_standard(url, params, onSuccess)
    {
    	var ms = new Date().getTime();
    	params = (params)?(params + '&ms=' + ms):('ms=' + ms);
    	try
    	{
    		var xhr = getXhr();
    		xhr.onreadystatechange = function()
    		{
    			if (onSuccess && xhr.readyState == 4)
    			{
    				if (xhr.status == 200)
    				{
    					onSuccess(true, xhr.responseText);
    				}
    				else
    				{
    					onSuccess(false, "Erreur : Le serveur ne répond pas.");
    				}
    			}
    		}
    		xhr.open("GET", (url + "?" + params), true);
    		xhr.send(null);
    		return true;
    	}
    	catch (e)
    	{
    		return false;
    	}
    } // merci à Bovino et marcha ;-)
    // exemple d'appel :
    var monElement = document.getElementById(idElement);
    var monUrl = "./repertoire/page.php";
    var resultat_ajax = appel_ajax_standard(monUrl, "superParam=chouetteValeur", function(succes, retour) { 
    	if (succes) monElement.appendChild(document.createTextNode(retour));
    	else alert(retour);
    });
    if (!resultat_ajax) { alert("Une défaillance ajax a empêché ce traitement de s'effectuer. Veuillez contacter votre ragondin d'appartement."); }
    Je vais aussi me pencher sur l'implémentation de l'objet options suggéré par marcha et je vous tiens au jus

    ...pour les linguistes et les curieux >>> générateur de phrases aléatoires

    __________________

  15. #15
    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 : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Points : 2 351
    Points
    2 351
    Par défaut
    Ben disons que onSuccess devrait être appelé en cas de succès comme son nom l'indique :-)

    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
    38
    39
    40
    41
    42
    43
    44
    45
     
    function appel_ajax_standard(url, params, options)
    {
    	options = options || { }; // si option non passé on crée un objet vide
    	...    
    	try
    	{
    		var xhr = getXhr();
    		xhr.onreadystatechange = function()
    		{
    			if (xhr.readyState == 4)
    			{
    				if (xhr.status == 200)
    				{
    					if(options.onSuccess) options.onSuccess(xhr.responseText, xhr); // passer xhr peut aussi être pratique
    				}
    				else
    				{
    					if(options.onFailure) options.onFailure(xhr);
    				}
    			}
    		}
    		xhr.open("GET", (url + "?" + params), true);
    		xhr.send(null);
    		return true;
    	}
    	catch (e)
    	{
    		return false;
    	}
    }
    // exemple d'appel :
    var monElement = document.getElementById(idElement);
    var monUrl = "./repertoire/page.php";
    var resultat_ajax = appel_ajax_standard(monUrl, "superParam=chouetteValeur", { 
      onSuccess: function(retour) { 
    	monElement.appendChild(document.createTextNode(retour));
      },
      onFailure: ajaxErrorHandler
    });
    if (!resultat_ajax) { alert("Une défaillance ajax a empêché ce traitement de s'effectuer. Veuillez contacter votre ragondin d'appartement."); }
     
    function ajaxErrorHandler(xhr) {
      alert("Erreur Ajax " + xhr.status); // par exemple
    }
    Si ton code fait plus d'une ligne, c'est que tu as mal choisi ton langage !

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

    Informations professionnelles :
    Activité : POOête

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 652
    Points : 4 164
    Points
    4 164
    Par défaut
    Hum

    Pas eu le temps de m'y mettre entre midi et tu m'as pris de vitesse... merci beaucoup marcha c'est vraiment chouette comme ça

    Si jamais après utilisation je découvre d'autres améliorations à faire, je les posterai ici.. mais en attendant merci à tous ! ^^

    ...pour les linguistes et les curieux >>> générateur de phrases aléatoires

    __________________

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