Programmation asynchrone en JavaScript : guide complet

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction à la programmation asynchrone en JavaScript



JavaScript est un langage monothread avec une boucle d'événements (Event Loop) non bloquante. Cela signifie qu'une seule opération est exécutée à un moment donné, mais grâce à l'asynchronisme, nous pouvons ne pas attendre la fin des tâches lentes (lecture de fichier, requête API, timer) et continuer l'exécution d'autre code. Dans cet article, nous allons aborder tous les concepts clés de la programmation asynchrone dans l'environnement Node.js, des callbacks à la syntaxe moderne async/await.



La programmation asynchrone permet de créer des applications serveur hautes performances qui traitent des milliers de requêtes sans bloquer le thread principal. Comprendre ce paradigme est une compétence obligatoire pour tout développeur JavaScript.



1. Fonctions Callback et le problème du Callback Hell



Historiquement, le premier mécanisme d'asynchronisme en JavaScript était les callbacks — des fonctions qui sont appelées après la fin d'une opération asynchrone.



Exemple de callback simple



const fs = require('fs');

// Lecture asynchrone d'un fichierfs.readFile('example.txt', 'utf8', (err, data) => { if (err) { console.error('Erreur de lecture :', err); return; } console.log('Contenu du fichier :', data);});

console.log('Ce message apparaîtra avant le contenu du fichier');


Le problème survient lorsqu'il faut exécuter plusieurs opérations asynchrones séquentielles. L'imbrication des callbacks augmente et le code devient illisible — ce phénomène est appelé "Callback Hell" ou "L'enfer des callbacks".



Exemple de Callback Hell



fs.readFile('file1.txt', (err, data1) => {    if (err) throw err;    fs.readFile('file2.txt', (err, data2) => {        if (err) throw err;        fs.readFile('file3.txt', (err, data3) => {            if (err) throw err;            // Traitement des trois fichiers            console.log(data1 + data2 + data3);        });    });});


Un tel code est difficile à maintenir, tester et déboguer. La solution à ce problème est venue avec l'apparition des Promise.



2. Promise : se libérer du Callback Hell



Une Promise (promesse) est un objet qui représente le résultat d'une opération asynchrone : exécution réussie (resolve) ou erreur (reject). La Promise permet de construire des chaînes d'appels, rendant le code plus plat et lisible.



Création et utilisation d'une Promise



// Fonction retournant une Promiseconst readFilePromise = (filename) => {    return new Promise((resolve, reject) => {        fs.readFile(filename, 'utf8', (err, data) => {            if (err) reject(err);            else resolve(data);        });    });};

// UtilisationreadFilePromise('file1.txt') .then(data => { console.log('Fichier lu :', data); return readFilePromise('file2.txt'); }) .then(data => { console.log('Deuxième fichier :', data); }) .catch(err => { console.error('Erreur :', err); });


Méthodes Promise.all et Promise.race



Pour l'exécution parallèle de plusieurs opérations asynchrones, il existe des méthodes statiques utiles :



  • Promise.all() — attend l'exécution de toutes les promesses. Si au moins une se termine par une erreur, l'ensemble Promise.all passe à l'état rejected.
  • Promise.race() — retourne le résultat de la première promesse terminée (succès ou erreur).
  • Promise.allSettled() — attend la fin de toutes les promesses, retourne les résultats de chacune (succès ou erreur).


const promise1 = readFilePromise('file1.txt');const promise2 = readFilePromise('file2.txt');const promise3 = readFilePromise('file3.txt');

Promise.all([promise1, promise2, promise3]) .then(results => { console.log('Tous les fichiers sont lus :', results); }) .catch(err

Blogs

Book Recommendations