JavaScript async/await
Avant d'expliquer async/await, nous devons comprendre les concepts de programmation asynchrone en JavaScript ; vous pouvez vous référer à :Programmation asynchrone en JavaScript。
JavaScript est un langage mono-thread, ce qui signifie qu'il ne peut exécuter qu'une tâche à la fois. Pour éviter que les tâches de longue durée ne bloquent le thread principal, JavaScript utilise un modèle de programmation asynchrone.
Asynchrone vs synchrone
- Programmation synchrone: Le code s'exécute séquentiellement, et l'opération suivante ne s'exécute qu'après la fin de la précédente.
- Programmation asynchrone: Certaines opérations sont placées dans la « file de tâches ». Le thread principal continue d'exécuter le code suivant et traite les tâches de la file lorsque le thread principal est inactif.

Exemples
console.log('1');
console.log('2');
// Sortie : 1, 2
// Exemple asynchrone
console.log('1');
setTimeout(() => console.log('2'), 0);
console.log('3');
// Sortie : 1, 3, 2
Le problème des fonctions de rappel
Avant async/await, JavaScript utilisait principalement des fonctions de rappel pour gérer les opérations asynchrones, mais cela pouvait conduire à l'« enfer des callbacks ».
Exemples
getMoreData(a, fonction(b) {
getMoreData(b, fonction(c) {
getMoreData(c, fonction(d) {
console.log(d);
});
});
});
});
Cette structure imbriquée rend le code difficile à lire et à maintenir.
Introduction de Promise
ES6 a introduit l'objet Promise pour résoudre le problème de l'enfer des callbacks.
Exemples
return new Promise((resolve, reject) => {
// Opération asynchrone
setTimeout(() => resolve('data'), 1000);
});
}
getData()
.then(data => {
console.log(data);
return getMoreData(data);
})
.then(moreData => {
console.log(moreData);
})
.catch(error => {
console.error(error);
});
Bien que Promise ait amélioré le problème des callbacks, les appels chaînés then() ne sont toujours pas assez intuitifs.
Syntaxe async/await
ES2017 a introduit async/await, qui est construit sur Promise et fait ressembler le code asynchrone à du code synchrone.
Fonctions async
Ajoutez le mot-clé async avant une déclaration de fonction pour indiquer que la fonction est asynchrone :
// Corps de la fonction
}
Les fonctions async renvoient toujours une Promise :
- Si la valeur de retour n'est pas une Promise, elle sera automatiquement encapsulée dans une Promise résolue
- Si une exception est levée, une Promise rejetée est renvoyée
Expressions await
await ne peut être utilisé qu'à l'intérieur de fonctions async :
const result = await somePromise;
console.log(result);
}
await met en pause l'exécution de la fonction async jusqu'à ce que la Promise soit réglée :
- Si la Promise est résolue, la valeur résolue est renvoyée
- Si la Promise est rejetée, une erreur est levée (qui peut être interceptée avec try/catch)
Exemples d'applications pratiques
Utilisation de base
Exemples
return new Promise(resolve => setTimeout(resolve, ms));
}
async function showMessage() {
console.log('Start');
await delay(1000);
console.log('After 1 second');
await delay(1000);
console.log('Après encore 1 seconde');
}
showMessage();
Gestion des erreurs
Exemples
try {
const response = await fetch('https://api.example.com/user');
if (!response.ok) {
throw new Error('La réponse du réseau n'est pas correcte');
}
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Échec de la récupération des données :', error);
}
}
Exécution parallèle
Si vous devez exécuter plusieurs opérations asynchrones en parallèle, vous pouvez utiliser Promise.all :
Exemples
const [userData, productData] = await Promise.all([
fetch('/api/user'),
fetch('/api/products')
]);
const user = await userData.json();
const products = await productData.json();
return { user, products };
}
Problèmes courants et bonnes pratiques
1. N'oubliez pas await
Exemples
async function example() {
const data = fetch('/api'); // await manquant
console.log(data); // Affiche un objet Promise
}
// Exemple correct
async function example() {
const data = await fetch('/api');
console.log(data); // Affiche les données réelles
}
2. Éviter l'async inutile
Exemples
async function unnecessaryAsync() {
return 42;
}
// Manière plus simple de l'écrire
function simpleFunction() {
return 42;
}
3. await de premier niveau
await peut être utilisé directement au niveau supérieur d'un module (fonctionnalité ES2022) :
Exemples
const data = await fetch('/api');
console.log(data);
4. Considérations sur les performances
- Exécution séquentielle vs exécution parallèle : utilisez Promise.all de manière appropriée pour améliorer les performances
- Gestion des erreurs : assurez-vous que toutes les erreurs possibles sont capturées
async/await vs Promise traditionnelle
| Fonctionnalité | async/await | Promise then/catch |
|---|---|---|
| Lisibilité | Élevée, similaire au code synchrone | Moyenne, appels chaînés |
| Gestion des erreurs | Utilise try/catch | Utilise .catch() |
| Débogage | Plus facile, avec une pile d'appels claire | Plus difficile, la pile d'appels peut être floue |
| Structure du code | Plus plate | Imbriquée ou chaînée |
Résumé
async/await est une amélioration majeure de la programmation asynchrone en JavaScript. Il :
- Rend le code asynchrone plus lisible et plus maintenable
- Est basé sur Promise et compatible avec le code Promise existant
- Fournit une manière plus intuitive de gérer les erreurs
- Améliore l'expérience de débogage
Bien que async/await ne remplace pas complètement Promise, dans la plupart des cas, cela offre une solution plus élégante. Comprendre comment async/await fonctionne et ses bonnes pratiques améliorera grandement vos compétences en programmation asynchrone JavaScript.
Autres extensions