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 :

Faire du synchrone avec le l'asynchrone


Sujet :

JavaScript

  1. #1
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut Faire du synchrone avec le l'asynchrone
    Bonjour,

    Je recherche une solution pour transformer un bout de code asynchrone, à base de loopback multiples, en une méthode synchrone qui puisse me retourner une simple valeur une fois que tout le code asynchrone a été exécuté.

    Je ne sais pas du tout comment faire, et la bidouille que j'avais utilisé juqu'à présent ne fonctionne pas.

    Contexte : j'enrichis une application web qui utilise un framework que je ne peux pas modifier.

    Parmis les fonctionalités utlisées, j'ai :

    "QueryState" : attribut sur un bouton qui permet de tester le résultat d'une fonction synchrone. Cette fonction retourne une structure { visible: bool, disabled: bool } afin de déterminer si le bouton est visible et cliquable, en fonction de l'âge du capitaine.

    Et dans cette fonction synchrone, j'ai besoin de rechercher des données en base.
    J'utilise alors une fonction "u8.services.queries.execute(statement, loopback);"

    Le loopback est alors exécuté une fois que la requête a été exécutée, et me permet de lire les résutlats.

    Exemple :
    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
     
    				u8.services.queries.execute(
    					{
    						statement: "select (TenantNo, MA.Contact) from (FI) where (CoGrp='" + u8.CU.Common.Uid2StaNo(uid) + "' AND CoNo='" + u8.CU.Common.Uid2SerNo(uid) + "') plus (MA) where (Contact='#6' AND Subject='Envoi des CGV')"
    					}, 
    					function (sender, args)
    					{
    						let visible = false;
    						if (args.resultSet != null && args.resultSet.rows != null && args.resultSet.rows.length > 0)
    						{
    							const FI_TenNo = args.resultSet.rows[0].values[0];
    							const MA_Type = args.resultSet.rows[0].values[1];
    							if (FI_TenNo >= 8000 && FI_TenNo <= 8007)
    							{
    								if (MA_Type == null)
    								{
    									visible = true;
    								}
    							}
    						}
    						// Ci-dessous la bidouille que je souhaite retirer de mon code
    						button.visible = visible;
    						button._updateView();
    					}
    				);

    Jusqu'à présent, quand j'étais dans ce cas de figure, je retournais après l'appel à la fonction asynchrone un querystate qui cache le bouton, puis dans le loopback je venais modifier directement les attributs du bouton pour le faire réapparaître en cas de besoin.
    Ca, ça marche très bien quand le QuaryState est exécuté qu'une seule fois au chargement de la page : la page charge, puis après quelques dixièmes de secondes, le bouton apparaît.

    Sauf que là, je suis dans un cas où le QueryState va être testé toutes les secondes, histoire de modifier l'apparance du bouton en fonction de ce qui a pu être modifié dans d'autres onglets ou par d'autres personnes, sans devoir recharger la page.

    Et ma bidouille fait que le bouton clignotte du coup...

    Je cherche donc une solution pour faire un truc du genre :

    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
     
    let visible = false;
    u8.services.queries.execute(
    					{
    						statement: "select (TenantNo, MA.Contact) from (FI) where (CoGrp='" + u8.CU.Common.Uid2StaNo(uid) + "' AND CoNo='" + u8.CU.Common.Uid2SerNo(uid) + "') plus (MA) where (Contact='#6' AND Subject='Envoi des CGV')"
    					}, 
    					function (sender, args)
    					{
    						if (args.resultSet != null && args.resultSet.rows != null && args.resultSet.rows.length > 0)
    						{
    							const FI_TenNo = args.resultSet.rows[0].values[0];
    							const MA_Type = args.resultSet.rows[0].values[1];
    							if (FI_TenNo >= 8000 && FI_TenNo <= 8007)
    							{
    								if (MA_Type == null)
    								{
    									visible = true;
    								}
    							}
    						}
    					}
    				).wait();
    return { visible: visible, disabled: false }

    Comment faire ?

  2. #2
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 571
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 571
    Par défaut
    si vous laissez visible = false au début de la fonction anonyme, vous avez aussi le clignotement du bouton ?

  3. #3
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Oui, le souci, c'est qu'avant de savoir si le bouton doit être visible ou non, je le masque, afin que personne ne clique dessus pendant que le programme cherche à savoir s'il faut l'afficher ou non.
    Et après quelques dixièmes de seconde, on a le résultat de la requête, et on sait si on doit l'afficher ou non.
    => Si on doit l'afficher, à ce moment le bouton apparaît.

    Mais vu que la fonction est relancée environ toutes les secondes, le bouton passe son temps à disparaître et réapparaître.

    Le but serait de ne toucher à l'aspect du bouton qu'une fois qu'on sait si on doit l'afficher ou non.

    A savoir que l'affichage de la page est conditionné à la sortie de la fonction qui permet de faire le test de visibilité du bouton. Donc si on attends la fonction quelques dixièmes de secondes, la page va attendre gentillement.
    Une fois affichée, le bouton est juste non cliquable le temps du test, et le clic bufferisé, donc on ne s'en rend même pas compte quand on clique sur le bouton : ça fait rien quelques dixièmes de seconde tout au plus et ensuite ça effectue l'action du bouton (sauf s'il est devenu non visible ou non cliquable). Rien qui soit dérangeant au niveau IHM en tout cas.

  4. #4
    Expert confirmé Avatar de Toufik83
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    2 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

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

    Informations forums :
    Inscription : Janvier 2012
    Messages : 2 496
    Par défaut
    Bonjour,

    Quelque chose comme ça ?
    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
    async function checkVisibility(uid) {
      return new Promise((resolve, reject) => {
        u8.services.queries.execute(
          {
            statement: `select (TenantNo, MA.Contact) from (FI) where (CoGrp='${u8.CU.Common.Uid2StaNo(uid)}' AND CoNo='${u8.CU.Common.Uid2SerNo(uid)}') plus (MA) where (Contact='#6' AND Subject='Envoi des CGV')`
          },
          function (sender, args) {
            let visible = false;
            if (args.resultSet != null && args.resultSet.rows != null && args.resultSet.rows.length > 0) {
              const FI_TenNo = args.resultSet.rows[0].values[0];
              const MA_Type = args.resultSet.rows[0].values[1];
              if (FI_TenNo >= 8000 && FI_TenNo <= 8007) {
                if (MA_Type == null) {
                  visible = true;
                }
              }
            }
            resolve(visible); // Résoudre la promesse avec la valeur de visibility      
        });
      });
    }
     
    // Exemple d'usage:  faire appelle à la fonction checkVisibility(uid) à l'intérieur de la fonction asynchrone updateButtonVisibility
    async function updateButtonVisibility(uid) {
      const isVisible = await checkVisibility(uid); // Attendre le retour de la fonction
      button.visible = isVisible;
      button._updateView();
    }
     
    // Et finalement exécuter la fonction
    updateButtonVisibility(someUid); // someUid est le paramètre qui sera passé à checkVisibility
    Explication de code :
    • new Promise((resolve, rejet) => { ... }); : Dans la fonction checkVisibility, nous créons une nouvelle promesse. La fonction de résolution est ce que nous appellerons lorsque l'opération asynchrone se termine avec succès, et rejet est ce que nous appellerions en cas d'échec (nous n'utilisons pas rejet dans cet exemple, mais il est de bonne pratique d'inclure la gestion des erreurs).

    • solve(visible); : Dans le rappel de u8.services.queries.execute, après avoir déterminé la valeur visible, nous appelons resolve(visible). Cela remplit la promesse et la valeur visible devient le résultat de la promesse.

    • async function updateButtonVisibility(uid): C'est une fonction asynchrone, elle vous permet d'utiliser le mot clé await.

    • const isVisible = await checkVisibility(uid); : C'est là que la magie opère. await checkVisibility(uid) suspend l'exécution de updateButtonVisibility jusqu'à ce que la promesse renvoyée par checkVisibility soit résolue (c'est-à-dire jusqu'à ce que la requête se termine et que la valeur visible soit déterminée). La variable isVisible contiendra alors la valeur résolue (vrai ou faux).


    Cette approche est la manière standard et recommandée pour gérer les opérations asynchrones en JavaScript. Cela évite de bloquer le thread principal et rend votre code beaucoup plus organisé et maintenable. N'oubliez pas d'adapter la gestion des erreurs (en utilisant rejet dans la promesse et essayez...catch autour de l'appel d'attente) selon les besoins de votre application.

Discussions similaires

  1. [C#]Travailler en synchrone avec des objets asynchrone
    Par mister3957 dans le forum Windows Forms
    Réponses: 3
    Dernier message: 19/10/2006, 18h12
  2. Problème unit CRT pour Faire du Pascal avec Delphi
    Par alexmorel dans le forum Débuter
    Réponses: 4
    Dernier message: 01/06/2004, 17h13
  3. [INDY] comment faire un 'POST' avec idHTTP??
    Par gamez dans le forum Composants VCL
    Réponses: 5
    Dernier message: 17/05/2004, 19h02
  4. Faire une JFrame avec LookAndFeel
    Par aburner dans le forum Agents de placement/Fenêtres
    Réponses: 5
    Dernier message: 03/12/2003, 08h54
  5. faire des graphiques avec Perl
    Par And_the_problem_is dans le forum Modules
    Réponses: 2
    Dernier message: 16/07/2003, 16h08

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