Javascript
Async
Promises
Asynchrone
Es7
Maîtriser les Promises et Async/Await pour gérer le code asynchrone correctement sans callback hell.
Les Promises : qu'est-ce que c'est ?
Une Promise en JavaScript représente la finalisation (ou l'échec) d'une opération asynchrone et sa valeur résultante. C'est un objet qui relie un callback asynchrone à du code réactif.
À retenir : Une Promise encapsule une opération asynchrone et permet de chaîner des actions sans callback hell.
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Succès!');
}, 1000);
});
promise.then(result => {
console.info(result); // 'Succès!'
});
États d'une Promise : pending, fulfilled, rejected
Une Promise possède 3 états possibles :
- pending : opération en cours
- fulfilled : opération réussie (resolve)
- rejected : opération échouée (reject)
// ✓ Fulfilled
new Promise(resolve => {
resolve('Valeur');
}).then(value => console.info(value));
// ✗ Rejected
new Promise((resolve, reject) => {
reject(new Error('Erreur!'));
}).catch(error => console.error(error));
// Pending (ne terminera jamais)
new Promise(() => {
// Rien ne se passe
});
Methods des Promises : then, catch, finally
fetch('https://api.example.com/data')
.then(response => response.json()) // Chaîner then
.then(data => console.info(data))
.catch(error => console.error('Erreur:', error)) // Gérer l'erreur
.finally(() => console.info('Terminé')); // Toujours exécuté
Promise.all() : attendre plusieurs Promises
Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/posts').then(r => r.json()),
fetch('/api/comments').then(r => r.json())
])
.then(([users, posts, comments]) => {
console.info(users, posts, comments);
});
Async/Await : la syntaxe moderne
async/await est une syntaxe plus lisible pour travailler avec les Promises.
// Avec Promises
function fetchData() {
return fetch('/api/data')
.then(r => r.json())
.then(data => console.info(data));
}
// Avec async/await
async function fetchData() {
const response = await fetch('/api/data');
const data = await response.json();
console.info(data);
}
À retenir :
async marque une fonction comme asynchrone. await pause l'exécution jusqu'à ce que la Promise soit résolue.
Promises vs Async/Await : comparaison
| Aspect | Promises | Async/Await |
|---|---|---|
| Lisibilité | Chaînes de .then() | Code synchrone-like |
| Erreurs | .catch() | try/catch |
| Parallélisation | Promise.all() | Promise.all() |
| Debugging | Stacktraces moins claires | Stacktraces claires |
Gestion des erreurs
Avec Promises :
fetch('/api/data')
.then(r => r.json())
.catch(error => {
console.error('Erreur:', error.message);
});
Avec Async/Await :
async function getData() {
try {
const response = await fetch('/api/data');
const data = await response.json();
return data;
} catch (error) {
console.error('Erreur:', error.message);
return null;
}
}
Patterns et cas d'usage avancés
Pattern 1 : Retry avec délai
async function retryFetch(url, attempts = 3) {
for (let i = 0; i < attempts; i++) {
try {
return await fetch(url).then(r => r.json());
} catch (error) {
if (i === attempts - 1) throw error;
await new Promise(resolve => setTimeout(resolve, 1000));
}
}
}
Pattern 2 : Timeout
async function timeoutFetch(url, timeout = 5000) {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
try {
return await fetch(url, { signal: controller.signal });
} finally {
clearTimeout(id);
}
}