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

TypeScript Discussion :

Comment retourner un état vrai/faux avec une function async


Sujet :

TypeScript

  1. #1
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 202
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 202
    Par défaut Comment retourner un état vrai/faux avec une function async
    Bonjour à tous,

    J'utilise une fonction pour mettre à jour une valeur dans une base de donnée

    Code typescript : 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
     /* Save Chart settings */
        const saveChartSettings = async(field:string, value:number) => {
            console.log( "SensorID:", id_sensor , "DB field:", field, "Value:",JSON.stringify(value,null,1))
     
     
            try {
                const response = await fetch('https://api.site-site.ch/putChartSettings.inc.php', {
                    method: 'POST',
                    headers:{
                        accept:'application(json',
                        Authorisation: 'key',
                    },
                    body: JSON.stringify({
                        id_sensor: id_sensor,
                        field: field,
                        value: value
                    })
                })
     
                if(!response.ok){
                    setThresholdError("[Save Threshold] Failed to fetch the API (check the path)")
                }
     
                const json = await response.json();
                console.info("Response:", json);
     
                if(json.response=="200"){
                    return 1
                }
                else{
                   return 0
                }
     
            }catch(err){
                setThresholdError("[Save setting] Check API path. " + err)
            } finally {
     
            }
        }


    Je me rends compte que j'ai besoin que la fonction me retourne 1 ou un 0 si le champs a été mis à jour, ou si aucune modification à eu lieu. Une erreur doit returner la valuer -1.

    Pour le moment, j'ai ajouté 'reurn 1' et 'return 0'

    J'ai aussi modifié ceci comme cela

    Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if(saveChartSettings('border-color', value) == 1 ){
                setIsBorderColorSaved(1)
            }
            else{
                setIsBorderColorSaved(0)
            }

    Ce qui me génère une erreur
    Nom : Screenshot 2025-11-21 at 21.07.50.png
Affichages : 44
Taille : 37,0 Ko

    Mon problème est que je ne sais pas comment résoudre ce problème. Je comprends qu'il manque un élément await. Mais ou?

    J'ai essayé ceci sans succès

    Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if(await saveChartSettings('border-color', value) == 1 ){
                setIsBorderColorSaved(1)
            }
            else{
                setIsBorderColorSaved(0)
            }

    je ne comprends pas aussi la ntion de Promise, je suis un peu largué.

    Pouvez-vous m'éclairecir?

    Mercii

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 202
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 202
    Par défaut
    J'ai encore essayé cette version, sans succès

    Code typescript : 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
      /* Save Chart settings */
        const saveChartSettings = async(field:string, value:number) => {
            console.log( "SensorID:", id_sensor , "DB field:", field, "Value:",JSON.stringify(value,null,1))
     
     
            return fetch('https://api.site-site.ch/putChartSettings.inc.php', {
                method: 'POST',
                    headers:{
                        accept:'application(json',
                        Authorisation: 'key',
                    },
                    body: JSON.stringify({
                        id_sensor: id_sensor,
                        field: field,
                        value: value
                    })
            }).then((r) => r.json) 
    }
     
    const r = saveChartSettings('boreder-color',1)
    console.log(r)
    console.log m'affiche
    {"_h": 0, "_i": 0, "_j": null, "_k": null}
    alors que je chercher la valeur de json.response
    (Dans mon fichier PHP (API) j'ai ceci (extrait)

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $payload = array(
    		'response'	=> 100,
    		'method'	=> "",
    		'id_sensor' => 0,
    		'field'		=> null,
    		'value'		=> null,
    		'temp'		=> "",
     
    	);
    // Ici le code qui va mettre à jour la base de donnée. Il va mofier response à 200 ou 202, 202 étant la réussite de la mise à jour
    echo json_encode($payload, JSON_NUMERIC_CHECK);

  3. #3
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 525
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 525
    Par défaut
    Citation Envoyé par pierrot10 Voir le message
    J'ai essayé ceci sans succès

    Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if(await saveChartSettings('border-color', value) == 1 ){
                setIsBorderColorSaved(1)
            }
            else{
                setIsBorderColorSaved(0)
            }
    Il manque effectivement await mais pour pouvoir utiliser ce mot-clé, la fonction dans laquelle il est utilisé doit elle-même être async.

    je ne comprends pas aussi la ntion de Promise, je suis un peu largué.
    C'est par là qu'il faut commencer, effectivement. Ce n'est pas trivial de prime abord et il faut effectivement pratiquer un peu pour comprendre comment elles fonctionnent, mais rien d'insurmontable.

    https://developer.mozilla.org/fr/doc...bjects/Promise

    Les promesses « Promise » sont un concept qui existe de longue date, mais qui a surtout été choisi puis normalisé au sein du JS pour implémenter les tâches asynchrones et faire du multitâche (coopératif) au sein d'un environnement qui en était totalement dépourvu au départ. C'est aussi l'API universelle utilisée dans toutes ces situations.

    C'est utile lorsque l'on utilise des appels qui sont nativement bloquants (par exemple alert()) ou lorsque l'on met en place un timer avec setTimeout() mais également, dans la situation inverse, lorsque l'on aimerait pouvoir implémenter un appel bloquant mais que ce n'est pas possible nativement. Cas typique : l'implémentation de boîtes de dialogues remplaçant alert() et confirm(), où l'on aimerait pouvoir attendre l'action de l'utilisateur sur le bouton « OK ».

    Formellement, elles fonctionnent à peu près ainsi :

    • Lorsque l'on veut implémenter une tâche asynchrone, on crée un objet Promise à l'aide de new Promise ;


    • On passe la fonction à attendre en constructeur de cet objet, ce qui rend déjà la syntaxe un peu ardue : var p = new Promise(function() {});


    • En réalité, cette fonction en particulier n'est pas forcément celle que l'on va attendre mais celle qui, à tout le moins, va initialiser le processus et lancer le travail à faire. En conséquence, elle peut tout aussi bien attendre elle-même si elle le peut (appel bloquant) que ressortir immédiatement, avec ou sans return. Si elle renvoie une valeur avec return, celle-ci sera ignorée ;


    • À cette fonction, la promesse va passer deux fonctions resolve et reject sous forme d'arguments. La fonction doit donc en tenir compte dans sa définition : var p = new Promise(function(resolve, reject) {…});


    • C'est uniquement à l'appel d'une de ses deux fonctions que la promesse sera résolue, qu'elle soit considérée comme tenue (parce que le processus a abouti normalement) ou qu'elle ait échoué en cas de problème ;


    • Ces deux appels fonctionnent de la même façon et attendent en argument la valeur de retour de la Promesse toute entière ;


    • Si le processus réussit et va jusqu'à son terme, celui-ci appelle resolve(valeur de retour) et sort, pour indiquer que tout s'est bien passé et que l'on peut continuer. Si toutefois ce processus va bien jusqu'à son terme mais qu'il s'est soldé par un échec, c'est bien resolve qu'il faut appeler également, en renvoyant la valeur appropriée, car on reste dans le cadre d'un fonctionnement normal (c'est important) ;


    • Si par contre une erreur a eu lieu et que celle-ci a empêché de mener les opérations jusqu'à leur terme, on appelle alors reject(valeur de retour) pour indiquer que la promesse n'a pas pu être tenue. Dans ce cas, une exception est lancée et le programme s'interrompt avec un message d'erreur dans la console, sauf si l'exception est rattrapée d'une manière ou d'une autre (voir plus bas).


    Donc, par exemple, pour implémenter une boîte de dialogue, la fonction initiale passée au constructeur peut se charger (ou pas) d'afficher la boîte proprement dite, mais elle va surtout faire en sorte que resolve soit appelée lorsque l'on clique sur le bouton. La meilleure façon de le faire est d'associer resolve à la propriété onclick, en utilisant bind pour l'associer à son code de retour.

    Une fois l'objet Promise dûment construit, il propose plusieurs méthodes qui permettent de contrôler le déroulement des opérations. Parmi elles :

    • .then(), ou « alors », qui permet d'indiquer ce qu'il faut faire ensuite dès que la Promesse est déclarée tenue. Là encore, on passe la fonction à exécuter comme argument de then() mais la fonction elle-même fonctionnera un poil différemment : elle recevra en argument unique le code de retour de la promesse (plus éventuellement reject), et son code de retour, cette fois, aura de l'importance ;
      .catch(), qui permet de mettre directement en place un dispositif d'interception de l'exception au cas où la promesse serait brisée. Sinon, tu peux la rattraper en dehors avec un try { }*catch {*} au bon endroit.


    Chaque fois que tu appelles la méthode .then() d'une promesse, la fonction passée en argument est ajoutée à la liste des opérations à faire dès que la promesse aura été tenue. Détail important : cette méthode peut être appelée même si la promesse a déjà été tenue, auquel cas l'exécution de la fonction sera immédiate. C'est important car l'opération initiale peut être très rapide, et peut se terminer avant même que les appels successifs à .then n'aient eu le temps d'avoir lieu.

    Enfin, dernier détail mais non des moindres : chaque appel à .then retourne… une autre Promesse ! C'est ce qui te permet de faire des « then en cascade », dont tu trouveras le détail derrière le lien ci-dessous ou dont nous parlerons dans un prochain commentaire. Cette promesse est automatiquement résolue à la fin de la fonction (sauf appel explicite à reject) et la valeur qui est en principe passée à resolve() est ici celle qui est renvoyée par return.

    async/await

    Tout ceci nous amène à présent à async/await, qui ont été introduits a posteriori.

    Il s'agit d'une facilité de syntaxe qui nous évite avantageusement d'avoir à définir manuellement tout ce dont nous venons de parler, mais on comprend aisément que le problème reste le même : il ne suffit pas d'écrire « await » devant une fonction que l'on souhaite attendre pour en faire automatiquement un appel bloquant… La encore, il faudrait rendre la main au système d'une manière ou d'une autre en attendant sa conclusion, sinon le navigateur entier, ou à tout le moins l'onglet concerné, resterait figé en attendant sa résolution.

    Et ici se trouve la clé du mystère : toute fonction déclarée async renvoie en fait… une Promesse ! cet objet est construit et renvoyé immédiatement à l'appel de la fonction, et ne sera résolu qu'à la sortie de la fonction en utilisant le code renvoyé par return, comme avec .then.

    C'est le fait d'avoir justement une chaîne de promesse, qui a donc un début et une fin, qui permet d'implémenter await et d'attendre la résolution de ce qui le suit : await attend en réalité… un objet de type Promesse également, et renvoie ensuite son code de résolution.

  4. #4
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 202
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 202
    Par défaut
    Hello,

    Milles merci pour ta réponse et tes explications. Je m'excuse aussi de te répndre aussi tardivement. Je vais lire encore plus attentivement tes riches explications.

    Avant de voir ta réponse, j'ai trouvé une alternative qui répond mieux à ma demande. Enfin, je pense. Je vais donc prendre le temps, cet après-midi, de comparer ta réponse. Mais je me permets de partager ce que j'ai trouvé.

    Avant, je dois donner des explications complémentaire.

    Je fais une application pour SmartPhone et j'ai une vue qui dois permettre de modifier les caractéristiques d'un graph. Quand on modifie l'un d'entre eux, l'App fait appelle à un API qui va faire la requete MySQL. Elle doit retourner une réponse pour afficher la validation.

    Nom : Simulator Screenshot.png
Affichages : 10
Taille : 238,0 Ko

    J'ai donc 7 dropbox. Chacun fait appelle à une fonction (etc)
    onDroDown1Change("nom_du_champs_db", value)
    onDroDown2Change("nom_du_champs_db", value)
    onDroDown3Change("nom_du_champs_db", value)
    Le problème que j'avais, est que je n'arrivais à retourner la valeur de 200 (validation) pour LE champs modifier. C'est pourquoi je voulais faire ceci

    Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function onDropDown1Change(value:number){
            setBorderWidth(value)
            if(saveChartSettings('border_width', value)==200){
            setBorderWidthValidate(true)
           }else{
           setBorderWidthValidate(false)
           }
        }
    Evidemment, ci-dessus, ca me retourne une erreur qui fait le sujet de mon post.

    Ce que j'ai fait

    Dans mon fichier PHP (API) j'ai créé une array qui définit les états des 7 paramètres à -1


    réponse:
    -1 = erreur ou pas de requete MyQL
    0 = pas de changement (la valeur n'est pas différente mais la requete MySQL s'est produite)
    1 = changement réussi
    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $datasets = array(
    		'response'		=> 100,
    		'method'		=> "",
    		'id_sensor' 	=> 0,
    		'value'			=> null,
    		'chart_style' 	=> -1,
    		'border_color'	=> -1,
    		'border_width'	=> -1,
    		'fill_background'=> -1,
    		'background_color' => -1,
    		'point_radius'	=> -1,
    		'point_style'	=> -1
     
    	);

    Puis après ma requête, l'un des 7 paramètre passera a 1 ou 0 (en fonction du paramètre modifier) de manière à ce que ma réponse soit, par exemple

    Code JSON : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     {
       "background_color": -1, 
       "border_color": 1, 
       "border_width": -1, 
       "chart_style": -1, 
       "fill_background": -1, 
       "id_sensor": 5, 
       "method": "POST", 
       "point_radius": -1, 
       "point_style": -1, 
       "response": 200, 
       "value": 2
    }
    (Ci-dessus, on a modifié la couleur de la courbe)

    Dans,ma vue, j'ai déclaré un type, puis un useState

    Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    type ChartSettings = {
        response: number,
    	method: string,
    	id_sensor: number,
    	value: number,
    	chart_style: number,
    	border_color: number,
    	border_width: number,
    	fill_background: number,
    	background_color: number,
    	point_radius: number,
    	point_style: number
    };
    const [chartSettings, setChartSettings] = useState<ChartSettings>()
    finalement, dans mon useQuery, je définis les valeurs de chertSettings en fonction de la réponse JSON
    Code typescript : 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
     
     
    /* Save Chart settings */
        const saveChartSettings = async(field:string, value:number) => {
            console.log( "SensorID:", id_sensor , "DB field:", field, "Value:",JSON.stringify(value,null,1))
             setIsFetchingThreshold(true)
            try {
                const response = await fetch('https://api.site-site.ch/putChartSettings.inc.php', {
                    method: 'POST',
                    headers:{
                        accept:'application(json',
                        Authorisation: 'key',
                    },
                    body: JSON.stringify({
                        id_sensor: id_sensor,
                        field: field,
                        value: value
                    })
                })
     
                if(!response.ok){
                    setThresholdError("[Save Threshold] Failed to fetch the API (check the path)")
                }
     
                const json = await response.json();
                console.info("Response: ", json);
                setChartSettings(json)
     
            }catch(err){
                setIsFetchingThreshold(false);
                setThresholdError("[Save setting] Check API path. " + err)
            } finally {
                 setIsFetchingThreshold(false)
            }
        }

    Puis avant chaque DropDown, je vérifie la validation de cette manaière (je donne 2 exemples sur 7, mais je pense que vous comprendrez le principe)

    Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    dropdownStyle={chartSettings?.chart_style==1 ? css.dropdownStyleValidate : css.dropdownStyle} // si 1, affiche un bordeWidth:1 et borderColor:'green' du DropDown, si autre, affiche le css par defaut
     
    dropdownStyle={chartSettings?.background_color==1 ? css.dropdownStyleValidate : css.dropdownStyle} // si 1, affiche un bordeWidth:1 et borderColor:'green' du DropDown, si autre, affiche le css par defaut

    Attention, ne pas confondre border_color et border_width définissent la largeur/couleur de la courbe et non du DorpDown


    Dans l'état, cela fonctionne très bien.

    Si pour le momenet, je n'ai pas tenu encore ta réponse dans cette solution, c'est que je l'ai trouvée avant de lire ton super message.

    Je vais l'étudier car c'est une méthode (async/await/Promise) que je ne maitrise pas bien. C'est donc l'occasion d'apprendre et de modifier ma solutions en conséquence.

    Qu'en penses-tu?

    Merciiiiii

Discussions similaires

  1. Requête avec critère vrai/faux avec en sortie faux une valeur nulle
    Par jaygria dans le forum Requêtes et SQL.
    Réponses: 17
    Dernier message: 21/06/2018, 00h00
  2. Réponses: 9
    Dernier message: 03/12/2007, 19h49
  3. Comment ne pas saturer l'ordi avec une boucle ?
    Par jenez dans le forum Windows
    Réponses: 5
    Dernier message: 01/10/2006, 00h01
  4. Réponses: 9
    Dernier message: 30/09/2006, 01h20
  5. Comment créer un site immobilier dynamique avec une base de données ?
    Par Alain troverti dans le forum Général Conception Web
    Réponses: 14
    Dernier message: 07/07/2006, 22h57

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