forum pédagogique programmation systèmes
Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.
Le Deal du moment :
Funko POP! Jumbo One Piece Kaido Dragon Form : ...
Voir le deal

Aller en bas
avatar
Admin
Admin
Messages : 112
Date d'inscription : 16/11/2018
https://progsys.forumactif.com

[A21] [EXPERTS] Problèmes de requêtes SQL qui se font trop tard ... initiation à Async/Await Empty [A21] [EXPERTS] Problèmes de requêtes SQL qui se font trop tard ... initiation à Async/Await

Lun 19 Juin - 15:34
Bonjour à tous,
Avant de prendre le temps d'intégrer ce contenu dans le site web du cours, je rédige vite-fait un billet ici pour vous permettre de modifier si besoin vos projets.

PROBLÈME :
Vous avez peut-être déjà rencontré ce problème dans le Labo 7 (SQL avec NodeJs pour Login) :
Vous lancez une requête SQL à un certain endroit de votre code, et vous vous attendez à ce que cette requête soit résolue et vous retourne des résultats, UN PEU PLUS LOIN DANS VOTRE CODE.
Cependant, comme vous le savez, NodeJs est Asynchrone et non-boquant, ce qui signifie que RIEN NE GARANTIT QUE LE CODE S'EXÉCUTE DE HAUT EN BAS.
Ainsi, le problème que vous rencontrez peut-être est que la variable JavaScript n'a pas encore reçu le résultat de la requête SQL alors que vous avez besoin de l'exploiter (exemple : l'envoyer à une page par EJS)

SOLUTION PROPOSÉE :
Il faut introduire dans le code un mécanisme qui garantit qu'une opération est complétée AVEC SUCCÈS avant de lancer la seconde opération QUI EN DÉPEND.
Ce type de mécanisme existe en JavaScript, c'est ce qu'on appelle un ASYNC/AWAIT.

Je vais vous montrer un extrait de code AVANT puis un autre APRÈS l'introduction de ce mécanisme, dans 2 endroits :
- la place qui CONSTRUIT l'opération qui doit être attendue (Je l'appelle "source")
- la place qui ATTEND que cette opération soit complétée avec succès (Je l'appelle "destination")

Dans mon exemple :
- le code "source" est dans  un fichier à part, un module qui ne s'occupe QUE de consulter la base de données (lancer un SELECT en SQL)
- le code "destination" est un extrait du index.js (route), à l'intérieur d'un GET ou d'un POST.

code "source" avant :
Code:

var myDb = require('./manageDb');
var querystring = 'SELECT * FROM tLabo7';
var query = myDb.query(querystring, function(err, rows, fields) {
 if (!err) {
   console.log("Ma requête SELECT est passée !");
   //result=rows;
   console.log(JSON.parse(JSON.stringify(rows)));
   module.exports = JSON.parse(JSON.stringify(rows));
 } else {
   console.log(err);
 };
});

code "source" après :
Code:

var myDb = require('./manageDb');
var querystring = 'SELECT * FROM utilisateurs';
var myPromise = new Promise((resolve, reject) => {
var query = myDb.query(querystring, function(err, rows, fields) {
    if (!err) {
      console.log("Ma requête SELECT est passée !");
      //result=rows;
      console.log(JSON.parse(JSON.stringify(rows)));
      //module.exports = JSON.parse(JSON.stringify(rows));
      resolve(JSON.parse(JSON.stringify(rows)));
    } else {
      console.log(err);
      reject("erreur select : " + err);
    };
  });
});
module.exports = myPromise;

Remarquez :
- "new Promise" qui crée un objet à retourner de type "promesse".
- "resolve" / "reject" qui retourne la promesse avec un succès ou un échec, ATTACHÉE à la variable-résultat

code "destination" avant :
Code:

[...]
    dbRows = require('../readDb');
[...]
      res.render('./pages/user', {userData : req.session.user, tab:dbRows});

code "destination" après :
Code:

[...]
    (async () => {
      try {
        var dbRows =  await require('../models/readDb');
        console.log("dbRows: ", dbRows);
[...]
      } catch(err) {
        console.log("ERREUR try/catch PROMISE : " + err);
      }
Remarquez :
- la structure try/catch (explications ici), qui capture une erreur pour rediriger le code selon une résolution de type succès/échec (resolve/reject)
- le mot clé "await" qui indique qu'on "attend" de récupérer le résultat d'une Promise
- la structure globale sous forme de "fonction asynchrone" (explications ici)

Voilà, en espérant avoir été suffisamment clair, et concis ...
[Admin]
Revenir en haut
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum