Skip to content

L'asynchrone avec les promesses et async/await

Les promesses en JavaScript représentent une valeur qui pourrait être disponible maintenant, dans le futur, ou jamais. Elles sont idéales pour travailler avec des opérations asynchrones, car elles offrent une manière plus lisible et gérable de traiter les résultats ou les erreurs provenant de ces opérations, par rapport aux callbacks classiques.

Une promesse peut être dans l'un des trois états suivants :

  1. Pending (En attente) : La valeur finale n'est pas encore disponible.
  2. Fulfilled (Résolue) : L'opération est terminée et la promesse a une valeur de résultat.
  3. Rejected (Rejetée) : Une erreur s'est produite pendant l'opération.

Les promesses ont deux méthodes principales pour interagir avec elles : .then() (qui s'exécute lorsque la promesse est résolue) et .catch() (qui s'exécute lorsque la promesse est rejetée).

Exemple avec la lecture de fichier asynchrone à l'aide de promesses et du module fs.promises de Node.js :

javascript
import { readFile } from 'fs/promises';

const lireFichier = async (chemin) => {
    try {
        const contenu = await readFile(chemin, 'utf8');
        console.log('Contenu du fichier:', contenu);
    } catch (err) {
        console.error('Erreur lors de la lecture du fichier:', err);
    }
};

lireFichier('monFichier.txt');
import { readFile } from 'fs/promises';

const lireFichier = async (chemin) => {
    try {
        const contenu = await readFile(chemin, 'utf8');
        console.log('Contenu du fichier:', contenu);
    } catch (err) {
        console.error('Erreur lors de la lecture du fichier:', err);
    }
};

lireFichier('monFichier.txt');

Explications :

  • Nous utilisons import { readFile } from 'fs/promises' pour importer la fonction readFile du module fs.promises.
  • La fonction lireFichier est déclarée avec async, ce qui signifie qu'elle peut utiliser await à l'intérieur pour attendre qu'une promesse soit résolue.
  • await readFile(chemin, 'utf8') attend que la promesse soit résolue (le fichier est lu) ou rejetée (une erreur se produit). Si tout se passe bien, la valeur résolue (le contenu du fichier) est affectée à la variable contenu. Sinon, une exception est levée et attrapée par le bloc catch.

1. Les Promesses et .then(), .catch()

Quand une fonction retourne une promesse, vous pouvez utiliser .then() pour accéder à la valeur une fois que la promesse est résolue. Si la promesse est rejetée (c'est-à-dire, une erreur se produit), vous pouvez attraper cette erreur avec .catch().

Exemple:

javascript
const promesseSimple = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('La promesse est résolue !');
        // Ou, si une erreur se produit :
        // reject('Une erreur est survenue.');
    }, 1000);
});

promesseSimple
    .then(valeur => {
        console.log(valeur);  // Affichera : 'La promesse est résolue !'
    })
    .catch(erreur => {
        console.error(erreur);  // Sera affiché si une erreur est rejetée
    });
const promesseSimple = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('La promesse est résolue !');
        // Ou, si une erreur se produit :
        // reject('Une erreur est survenue.');
    }, 1000);
});

promesseSimple
    .then(valeur => {
        console.log(valeur);  // Affichera : 'La promesse est résolue !'
    })
    .catch(erreur => {
        console.error(erreur);  // Sera affiché si une erreur est rejetée
    });

2. Promise.all()

Promise.all() prend un tableau de promesses et retourne une nouvelle promesse qui est résolue quand toutes les promesses du tableau sont résolues. Si l'une des promesses est rejetée, la promesse renvoyée par Promise.all() est également rejetée.

Exemple:

javascript
const promesse1 = Promise.resolve('Première valeur');
const promesse2 = Promise.resolve('Deuxième valeur');
const promesse3 = Promise.resolve('Troisième valeur');

Promise.all([promesse1, promesse2, promesse3])
    .then(valeurs => {
        console.log(valeurs);  // Affichera : ['Première valeur', 'Deuxième valeur', 'Troisième valeur']
    })
    .catch(erreur => {
        console.error(erreur);
    });
const promesse1 = Promise.resolve('Première valeur');
const promesse2 = Promise.resolve('Deuxième valeur');
const promesse3 = Promise.resolve('Troisième valeur');

Promise.all([promesse1, promesse2, promesse3])
    .then(valeurs => {
        console.log(valeurs);  // Affichera : ['Première valeur', 'Deuxième valeur', 'Troisième valeur']
    })
    .catch(erreur => {
        console.error(erreur);
    });

3. async/await

La syntaxe async/await permet d'écrire du code asynchrone qui ressemble beaucoup à du code synchrone. Une fonction déclarée avec async retourne toujours une promesse. À l'intérieur de cette fonction, vous pouvez utiliser await pour attendre qu'une promesse soit résolue.

Exemple:

javascript
async function obtenirValeur() {
    const resultat = await promesseSimple;  // Attend que la promesse soit résolue
    console.log(resultat);
}

obtenirValeur();
async function obtenirValeur() {
    const resultat = await promesseSimple;  // Attend que la promesse soit résolue
    console.log(resultat);
}

obtenirValeur();

Vous pouvez combiner async/await avec Promise.all() pour attendre que plusieurs promesses soient résolues :

javascript
async function obtenirToutesLesValeurs() {
    const valeurs = await Promise.all([promesse1, promesse2, promesse3]);
    console.log(valeurs);  // Affichera : ['Première valeur', 'Deuxième valeur', 'Troisième valeur']
}

obtenirToutesLesValeurs();
async function obtenirToutesLesValeurs() {
    const valeurs = await Promise.all([promesse1, promesse2, promesse3]);
    console.log(valeurs);  // Affichera : ['Première valeur', 'Deuxième valeur', 'Troisième valeur']
}

obtenirToutesLesValeurs();

A retenir

Les promesses sont un moyen puissant de gérer l'asynchronicité en JavaScript et dans Node.js. En utilisant .then(), .catch(), Promise.all(), et async/await, vous pouvez écrire du code asynchrone de manière plus propre, lisible, et gérable. La maîtrise de ces concepts est essentielle pour le développement moderne en JavaScript, car elle offre une flexibilité et une efficacité maximales lors de la gestion des opérations asynchrones.