Chapitre 4.5 : Async/await vs Promise
Temps d'étude : 30 minutes
1. Asynchronisme : Deux manières de gérer la "communication spatiale"
Imaginez que le Centre de Contrôle de Mission (CCM) envoie une commande à Mars. La réponse n'arrivera que dans quelques minutes. Comment organiser le travail pendant ce temps ?
Méthode 1 : "Protocole de rappel" (Promise avec .then()
)
Vous envoyez une commande et donnez l'instruction : "QUAND la réponse arrivera, ALORS exécute cette fonction". Cela ressemble à une chaîne d'événements.
Méthode 2 : "Mode d'attente" (Async/await) Vous dites : "Je VAIS ATTENDRE la réponse à cette commande, mais je ne bloquerai pas les autres pupitres de commande". C'est comme si vous mettiez en pause l'exécution de cette tâche spécifique, permettant au reste du CCM de continuer à fonctionner.
Les deux méthodes résolvent la même tâche : la gestion des opérations asynchrones. async/await
est simplement une syntaxe plus moderne et lisible qui fonctionne "au-dessus" des promesses.
💡 Analogie spatiale :
- Promise avec
.then()
: C'est comme écrire sur un post-it : "Quand le rover martien enverra la photo, la transmettre au département d'analyse."- Async/await : C'est comme dire à un assistant : "Attendez la photo du rover martien, pendant ce temps je m'occupe des calculs pour le lancement d'une nouvelle fusée."
2. Promise avec .then()
: La chaîne de commandes classique
C'est la manière fondamentale de travailler avec l'asynchronisme en JavaScript, que nous avons utilisée au chapitre 4.1.
Rappelons notre premier code :
function getIssPositionWithPromises() {
console.log('Envoi de la requête via le protocole "Promise"...');
fetch('http://api.open-notify.org/iss-now.json')
.then(response => {
// Étape 1 : Réponse reçue
if (!response.ok) {
throw new Error(`Erreur HTTP : ${response.status}`);
}
return response.json(); // On retourne une nouvelle promesse
})
.then(data => {
// Étape 2 : Données parsées
console.log('Données via le protocole "Promise" reçues :', data.iss_position);
})
.catch(error => {
// Étape 3 (Erreur) : Quelque chose s'est mal passé à l'une des étapes
console.error('Panne de communication via le protocole "Promise" :', error);
});
console.log('...commande envoyée, le CCM continue son travail...');
}
Avantages :
- Chaîne d'actions explicite.
- Convient bien aux opérations séquentielles simples.
Inconvénients :
- "Enfer des rappels" (Callback Hell) : Avec un grand nombre d'opérations asynchrones imbriquées, le code peut se transformer en une "échelle" de
.then()
difficile à lire. - La gestion des erreurs peut être moins intuitive.
3. Async/await : Le style synchrone moderne
async/await
est du "sucre syntaxique" au-dessus des promesses, qui permet d'écrire du code asynchrone comme s'il était synchrone.
Règles d'utilisation :
- Le mot-clé
await
ne peut être utilisé qu'à l'intérieur d'une fonction marquée commeasync
. await
est placé devant un appel qui retourne une promesse (par exemple,fetch()
ouresponse.json()
).await
"suspend" l'exécution de la fonctionasync
jusqu'à ce que la promesse soit résolue, et retourne son résultat.
Le même code, réécrit avec async/await
:
async function getIssPositionWithAsyncAwait() {
console.log('Envoi de la requête via le protocole "Async/await"...');
try {
// Étape 1 : On attend la réponse du serveur
const response = await fetch('http://api.open-notify.org/iss-now.json');
if (!response.ok) {
throw new Error(`Erreur HTTP : ${response.status}`);
}
// Étape 2 : On attend que le corps de la réponse soit converti en JSON
const data = await response.json();
console.log('Données via le protocole "Async/await" reçues :', data.iss_position);
} catch (error) {
// Étape 3 (Erreur) : On attrape toute erreur du bloc try
console.error('Panne de communication via le protocole "Async/await" :', error);
}
console.log('...commande envoyée, le CCM continue son travail...');
}
Avantages :
- Lisibilité : Le code ressemble presque à du code synchrone ordinaire, il est facile à lire de haut en bas.
- Gestion des erreurs : Utilise le bloc
try...catch
standard et familier. - Débogage : Beaucoup plus facile à déboguer, car on peut placer des points d'arrêt (breakpoints) sur chaque ligne avec
await
.
Inconvénients :
- Facile d'oublier
await
ouasync
, ce qui entraînera des erreurs.
4. Quand utiliser quel protocole ?
Situation | Approche recommandée | Pourquoi ? |
---|---|---|
La plupart des cas | async/await |
Code plus propre, plus facile à lire et à déboguer. C'est le standard moderne. |
Chaîne simple de 1-2 actions | Promise avec .then() |
Convient parfaitement, le code reste compact. |
Exécution parallèle de plusieurs requêtes | Promise.all() |
Cette méthode permet de lancer plusieurs promesses simultanément et d'attendre qu'elles se terminent toutes. async/await se combine parfaitement avec elle. |
Exemple avec Promise.all()
:
async function getParallelData() {
try {
// On lance les deux requêtes simultanément
const [shipsResponse, launchesResponse] = await Promise.all([
fetch('https://api.spacexdata.com/v4/rockets'),
fetch('https://api.spacexdata.com/v4/launches/latest')
]);
if (!shipsResponse.ok || !launchesResponse.ok) {
throw new Error('Une des requêtes a échoué !');
}
const rockets = await shipsResponse.json();
const latestLaunch = await launchesResponse.json();
console.log(`Nombre total de fusées dans la flotte : ${rockets.length}`);
console.log(`Dernier lancement : ${latestLaunch.name}`);
} catch (error) {
console.error('Erreur lors de la récupération des données parallèles :', error);
}
}
Quiz pour la consolidation
🚀 Résumé du chapitre :
Vous avez appris deux syntaxes pour gérer les opérations asynchrones et compris pourquoi async/await
est préférable dans la plupart des projets modernes.
- 🔗 Vous avez rafraîchi vos connaissances sur les Promise avec
.then()
. - 🛠️ Vous avez profondément compris comment fonctionne
async/await
et ses avantages. - ⚡ Vous avez découvert
Promise.all
pour l'exécution de requêtes parallèles.
Les protocoles de communication ont été étudiés ! Dans le dernier chapitre de cette section, nous rassemblerons toutes nos connaissances et achèverons notre "Centre de Contrôle de Mission", en créant une interface complète pour toutes les opérations CRUD.
📌 Pratique :
- Réécrivez toutes les fonctions de votre
app.js
qui utilisent encore.then()
, en utilisant la syntaxeasync/await
.- Essayez d'ajouter une autre requête à
Promise.all()
(par exemple, vershttps://api.spacexdata.com/v4/starlink
) et d'afficher les données.⚠️ En cas d'erreurs :
await is only valid in async functions
: Assurez-vous que la fonction où vous utilisezawait
est marquée commeasync
.- La variable contient
[object Promise]
: Vous avez oublié de placerawait
devant la fonction qui retourne une promesse.