Outils pour utilisateurs

Outils du site


code_language:javascript

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
code_language:javascript [2025/11/02 15:27]
74.7.227.242 ancienne révision (2025/11/02 13:14) restaurée
code_language:javascript [2025/11/02 15:51] (Version actuelle)
74.7.227.242 ancienne révision (2025/11/02 13:06) restaurée
Ligne 1571: Ligne 1571:
 Documentation setTimeout: https://www.w3schools.com/jsref/met_win_settimeout.asp Documentation setTimeout: https://www.w3schools.com/jsref/met_win_settimeout.asp
  
-=== Les autres "setTimeout" pour utiliser l'asynchrone en JavaScript === +=== Les autres "setTimeout" pour utiliser l'asynchrone en JavaScript ===
  
 +Il existe d'autres méthodes un peu moins répandues, voire très peu utilisées:
 +  * setInterval : fonctionne comme "setTimeout" , à ceci près qu'elle exécute la fonction passée en paramètre en boucle à une fréquence déterminée par le temps en millisecondes passé en second paramètre.Il suffira de passer la valeur de retour de setInterval à clearInterval pour stopper l'exécution en boucle de la fonction.
 +    * Documentation https://www.w3schools.com/jsref/met_win_setinterval.asp
 +  * setImmediate: Cette fonciton prend en seul paramètre la fonction à exécuter de façon synchrone. La fonction en question sera placée dans la file d'attente de l'event loop, mais va passer devant toutes les autres fonctions, sauf certaines spécifiques au Javascript.
 +    * Documentation: https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate
 +
 +=== Fonction asynchrone par nature ===
 +  * Les evenements: Sont toujours exécutés de façon asynchrone.
 +  * Les input/output aux sens large sont toujours exécutés de façon asynchrone.
 +  * Quelques autres... (callBack, Promise, et les Async/Await)
 +
 +=== CallBacks ===
 +
 +Une callback est simplement une fonction que vous définissez. Le principe de la callback est de la passer en paramètre d'une fonction asynchrone. Une fois que la fonction asynchrone a fini sa tâche, elle va appeler notre fonction callback en lui passant un résultat.
 +
 +exemple:
 +<code JavaScript [enable_line_numbers="true"]>
 +element.addEventListener('click', function(e) {
 +    // Do something here ... 
 +});
 +</code>
 +
 +Les callbacks sont faciles à comprendre et à utiliser, mais elles souffrent d'un gros problème de lisibilité du code, via ce qu'on appelle le callback hell. En effet, on se retrouve régulièrement dans des situations où on va imbriquer plusieurs couches de callbacks , rendant le code difficile à lire et pouvant générer des erreurs.
 +
 +
 +<code JavaScript [enable_line_numbers="true"]>
 +elt.addEventListener('click', function(e) {
 +    mysql.connect(function(err) {
 +        mysql.query(sql, function(err, result) {
 +            fs.readFile(filePath, function(err, data) {
 +                mysql.query(sql, function(err, result) {
 +                    // etc ...
 +                });
 +            });
 +        });
 +    }); 
 +});
 +</code>
 +C'est bien beau de gérer du code asynchrone, mais rien ne vous garantit que tout se soit bien passé. Il nous faut donc un mécanisme pour savoir si une erreur est survenue !
 +
 +=== Gerer les erreurs callbacks ===
 +Pour gérer les erreurs avec les callbacks, la méthode la plus utilisée est de prendre 2 paramètres dans notre callback. Le 2e paramètre est notre donnée et le 1er est l'erreur. Si elle n'est pas null ou undefined,  elle contiendra un message d'erreur indiquant qu'une erreur est intervenue.
 +
 +Si on reprend l'exemple ci-dessus, on voit par exemple que la lecture d'un fichier avec le module  fs  peut nous retourner une erreur :
 +
 +exemple: 
 +<code JavaScript [enable_line_numbers="true"]>
 +fs.readFile(filePath, function(err, data) {
 +    if (err) {
 +        throw err;
 +    }
 +    // Do something with data
 +});
 +</code>
 +
 +=== Promise ===
 +Lorsqu'on l'on exécute du code asynchrone, celui-ci va immédiatement nous retourner une "promesse" qu'un résultat nous sera envoyé prochainement.
 +
 +Cette promesse est en fait un objet "Promise" qui peut être "resolve" avec un résultat, ou "reject" avec une erreur.
 +
 +Lorsque l'on récupère une "Promise", on peut utiliser sa fonction "then()" pour exécuter du code dès que la promesse est résolue, et sa fonction "catch()" pour exécuter du code dès qu'une erreur est survenue.
 +
 +Exemple:
 +
 +<code JavaScript [enable_line_numbers="true"]>
 +functionThatReturnsAPromise()
 +    .then(function(data) {
 +        // Do somthing with data 
 +    })
 +    .catch(function(err) {
 +        // Do something with error
 +    });
 +</code>
 +Dans l'exemple ci-dessus, la fonction "functionThatReturnsAPromise" nous renvoie une  Promise . On peut donc utiliser sa fonction "then()" en lui passant une fonction qui sera exécutée dès qu'un résultat sera reçu (avec le résultat en question passé à notre fonction). On peut aussi utiliser sa fonction "catch()" en lui passant une fonction qui sera exécutée si une erreur est survenue (avec l'erreur en question passée à notre fonction).
 +
 +Le gros avantage est que l'on peut aussi chaîner les "Promise".
 +
 +exemple: 
 +<code JavaScript [enable_line_numbers="true"]>
 +returnAPromiseWithNumber2()
 +    .then(function(data) { // Data is 2
 +        return data + 1;
 +    })
 +    .then(function(data) { // Data is 3
 +        throw new Error('error');
 +    })
 +    .then(function(data) {
 +        // Not executed  
 +    })
 +    .catch(function(err) {
 +        return 5;
 +    })
 +    .then(function(data) { // Data is 5
 +        // Do something
 +    });
 +</code>
 +
 +Dans l'exemple ci-dessus, la fonction "returnAPromiseWithNumber2" nous renvoie une "Promise" qui va être résolue avec le nombre "2".
 +La première fonction "then()" va récupérer cette valeur.
 +Puis, dans cette fonction on retourne "2+1", ce qui cré une nouvelle "Promise" qui est immédiatement résolue avec "3".
 +Puis, dans le "then()" suivant, nous retournons une erreur.
 +De ce fait, le "then()" qui suit ne sera pas appelé et c'est le "catch()" suivant qui va être appelé avec l'erreur en question. Lui-même retourne une nouvelle valeur qui est transformée en "Promise" qui est immédiatement résolue avec la valeur "5". Le dernier "then()" va être exécuté avec cette valeur.
 +
 +"catch" intercepte les erreurs des "Promise".
 +
 +=== Async/Await ===
 +"async" et "await" sont 2 nouveaux mots clés qui permettent de gérer le code asynchrone de manière beaucoup plus intuitive, en bloquant l'exécution d'un code asynchrone jusqu'à ce qu'il retourne un résultat.
 +<code JavaScript [enable_line_numbers="true"]>
 +async function fonctionAsynchrone1() {/* code asynchrone */}
 +async function fonctionAsynchrone2() {/* code asynchrone */}
 +
 +async function fonctionAsynchrone3() {
 + const value1 = await fonctionAsynchrone1();
 + const value2 = await fonctionAsynchrone2();
 + return value1 + value2;
 +}
 +</code>
 +
 +Gerer des erreurs async/await
 +
 +async/await utilisant les "Promise", la levée d'une erreur se fait aussi par une exception.
 +Pour intercepter cette erreur, par contre, il suffit d'exécuter notre code asynchrone dans un bloc "try{] catch(e){}" , l'erreur étant envoyée dans le "catch".
 +
 +==== Parallélisez plusieurs requêtes HTTP ====
 +
 +=== Enchaînez des requêtes avec les callbacks ===
 +On peut formuler plusieurs requêtes serveur en parallèle puis ensuite les suivre avec une requête en séquence avec les callbacks.
 +
 +Pour cet exemple, nous partons du principe que nous avons accès à 2 fonctions (get  et  post). Elles font respectivement une requête "GET" et une requête "POST" et elles prennent en paramètre :
 +  * l'URL de la requête,
 +  * Une callback à executer quand on a le résultat (avec une variable d'erreur en premier paramètre).
 +
 +
 +<code JavaScript [enable_line_numbers="true"]>
 +var GETRequestCount = 0;
 +var GETRequestResults = [];
 +
 +function onGETRequestDone(err, result) {
 +    if (err) throw err;
 +    
 +    GETRequestCount++;
 +    GETRequestResults.push(result);
 +    
 +    if (GETRequestCount == 2) {
 +        post(url3, function(err, result) {
 +            if (err) throw err;
 +            
 +            // We are done here !
 +        });
 +    }
 +}
 +
 +get(url1, onGETRequestDone);
 +get(url2, onGETRequestDone);
 +</code>
 +
 +
 +Afin d'exécuter 2 requêtes "GET" en même temps, nous pouvons appeler 2 fois la fonction "get()". Etant donné que cette fonction est asynchrone, elle ne bloquera pas l'exécution du code. Ainsi l'autre fonciton "get()" sera aussi appelée alors que la première ne sera pas encore terminée. C'est comme ça qu'on peut avoir 2 requêtes en parallèle.
 +
 +Par contre, nous voulons exécuter une requête "POST" une fois que les 2 requêtes "GET" sont terminées, et pas avant! Pour ce faire, nous devons savoir si les requêtes "GET" sont terminées. C'est pour ça que la variable "GETRequestCount" est créée. On va l'incrémenter dans la fonction callback que l'on a envoyée aux appels à "get()", et si on atteint 2 (le nombre de requêtes "GET" qu'on a faites; alors on va exécuter la requête "POST".
 +
 +"GETRequestResults" sert à conserver les réponses des requêtes "GET", car on ne les a pas toutes les 2 en même temps.
 +
 +=== Enchaînez des requêtes avec les Promise ===
 +
 +Grâce à la fonction "Promise.all", voyons comment exécuter nos requêtes en parallèle et en séquence avec les "Promise".
 +
 +Pour cet exemple, nous partons du principe que nous avons accès à 2 fonctions ( "get" et "post" ) qui font respectivement une requête "GET" et une requête  POST  quand on leur passe en paramètre l'URL de la requête. Ces fonctions retourneront une  Promise  avec le résultat de la requête.
 +
 +<code JavaScript [enable_line_numbers="true"]>
 +Promise.all([get(url1), get(url2)])
 +    .then(function(results) {
 +        return Promise.all([results, post(url3)]];
 +    })
 +    .then(function(allResults) {
 +        // We are done here !
 +    });
 +</code>
 +
 +Ici, nous utilisons la fonction "Promise.all" qui prend en paramètre une liste de "Promise" (cela peut aussi être de simples valeurs qui sont alors transformées en "Promise" résolues), et qui permet de toutes les exécuter en parallèle et de retourner une nouvelle  Promise  qui sera résolue quand toutes les  Promise  seront résolues.
 +
 +Ainsi, la fonction "then()" recevra les résultats de toutes les "Promise" sous forme d'un tableau.
 +
 +Afin d'exécuter notre requête  POST  une fois que les requêtes "GET" sont terminées, nous l'exécutons donc dans la fonction "then()".
 +
 +Notez:
 +Notez que dans la fonction "then()", nous faisons encore une fois appel à la fonction  Promise.all  en lui passant les résultats des requêtes "GET" et notre requête "POST". Étant donné que "Promise.all" considère les simples valeurs comme des  Promise  résolues, cela nous permet, dans le prochain "then()", de récupérer une liste qui contient les résultats des requêtes "GET" et le résultat de la requête "POST" :"allResults = [ [ getResult1, getResult2 ], postResult ]".
 +
 +=== Enchaînez des requêtes avec les async/await ===
 +
 +Finalement, voyons comment exécuter le même code mais avec  async  /  await .
 +
 +Pour cet exemple, nous partons du principe que nous avons accès à 2 fonctions ( "get" et "post" ) qui font respectivement une requête "GET" et une requête "POST" quand on leur passe en paramètre l'URL de la requête. Ces fonctions sont asynchrones (avec le mot clé "async").
 +
 +<code JavaScript [enable_line_numbers="true"]>
 +async function requests() {
 +    var getResults = await Promise.all([get(url1), get(url2)]);
 +    var postResult = await post(url3);
 +    return [getResults, postResult];
 +}
 +
 +requests().then(function(allResults) {
 +    // We are done here !
 +});
 +</code>
 +
 +Nous utilisons aussi la fonction "Promise.all" dans ce code, car c'est comme ça que l'on peut exécuter des fonctions asynchrones en parallèle (rappelez-vous que "async" correspond en arrière-plan à une "Promise").
 +
 +Par contre, ici, nous utilisons "await" devant "Promise.all" afin d'attendre la fin de l'exécution des 2 requêtes "GET", puis nous utilisons "await" devant la requête "POST" afin d'attendre son résultat. Puis nous renvoyons un tableau avec tous les résultats.
 +
 +Lorsque nous appelons la fonction "requests()", ici, nous utilisons "then()" pour récupérer tous les résultats (mais vous auriez aussi pu utiliser "await" au sein d'une autre fonction avec le mot clé "async").
 +
 +==== Optimisation du code ====
 +
 +=== Linter, minifier, bundler, transpiler ===
 +
 +<code JavaScript [enable_line_numbers="true"]>
 +
 +</code>
  
  
code_language/javascript.1762097239.txt.gz · Dernière modification: 2025/11/02 15:27 de 74.7.227.242