JavaScript async/await
Résumé : dans ce tutoriel, vous apprendrez à écrire du code asynchrone en utilisant les mots-clés async
await
de JavaScript.
Notez que pour comprendre le fonctionnement de async
et await
, vous devez savoir comment fonctionnent les promesses.
Introduction aux mots-clés JavaScript async / await
Dans le passé, pour traiter les opérations asynchrones, vous utilisiez souvent les fonctions de rappel. Cependant, lorsque vous imbriquez de nombreuses fonctions de rappel, le code devient plus difficile à maintenir. Et vous vous retrouvez avec un problème notoire connu sous le nom de "callback hell".
Si vous voulez approfondir le sujet des [object Promise], un article leurres est dédié
Supposons que vous ayez besoin d'effectuer trois opérations asynchrones dans la séquence suivante :
- Sélectionner un utilisateur dans la base de données.
- Obtenir les services de l'utilisateur à partir d'une API.
- Calculer le coût du service en fonction des services du serveur.
Les fonctions suivantes illustrent ces trois tâches. Notez que nous utilisons la fonction
function getUser(userId, callback) {
console.log('Get user from the database.');
setTimeout(() => {
callback({
userId: userId,
username: 'john'
});
}, 1000);
}
function getServices(user, callback) {
console.log(`Get services of ${user.username} from the API.`);
setTimeout(() => {
callback(['Email', 'VPN', 'CDN']);
}, 2 * 1000);
}
function getServiceCost(services, callback) {
console.log(`Calculate service costs of ${services}.`);
setTimeout(() => {
callback(services.length * 100);
}, 3 * 1000);
}
La figure suivante montre les [object Promise] imbriquées :
getUser(100, (user) => {
getServices(user, (services) => {
getServiceCost(services, (cost) => {
console.log(`The service cost is ${cost}`);
});
});
});
Sortie :
Get user from the database.
Get services of john from the API.
Calculate service costs of Email,VPN,CDN.
The service cost is 300
Pour éviter ce problème de callback hell, ES6 a introduit les promesses qui vous permettent d'écrire du code asynchrone de manière plus gérable.
Tout d'abord, vous devez retourner une Promise dans chaque fonction :
function getUser(userId) {
return new Promise((resolve, reject) => {
console.log('Get user from the database.');
setTimeout(() => {
resolve({
userId: userId,
username: 'john'
});
}, 1000);
})
}
function getServices(user) {
return new Promise((resolve, reject) => {
console.log(`Get services of ${user.username} from the API.`);
setTimeout(() => {
resolve(['Email', 'VPN', 'CDN']);
}, 2 * 1000);
});
}
function getServiceCost(services) {
return new Promise((resolve, reject) => {
console.log(`Calculate service costs of ${services}.`);
setTimeout(() => {
resolve(services.length * 100);
}, 3 * 1000);
});
}
Ensuite vous pouvez chaîner les promesses
getUser(100)
.then(getServices)
.then(getServiceCost)
.then(console.log);
ES2017 a introduit les mots-clés
Si une fonction renvoie une promesse, vous pouvez placer le mot-clé await
devant l'appel de la fonction, comme ceci :
let result = await f();
La fonction
L'exemple suivant définit une fonction asynchrone qui appelle les trois opérations asynchrones en séquence :
async function showServiceCost() {
let user = await getUser(100);
let services = await getServices(user);
let cost = await getServiceCost(services);
console.log(`The service cost is ${cost}`);
}
showServiceCost();
Comme vous pouvez le voir, le code asynchrone ressemble maintenant au code synchrone.
Plongeons dans les mots-clés
Qu'est-ce que async en javascript ?
Le mot-clé
Pour définir une fonction asynchrone, vous placez le mot-clé async devant le mot-clé
async function sayHi() {
return 'Hi';
}
Les fonctions asynchrones s'exécutent de manière asynchrone via la boucle d'événements. Elles renvoient toujours une Promise.
Dans cet exemple, comme la fonction
sayHi().then(console.log);
L'effet est le même.
Outre les fonctions régulières, vous pouvez utiliser le mot-clé
// Fonction classique
let sayHi = async function () {
return 'Hi';
}
// Fonction fléchée
let sayHi = async () => 'Hi';
// Méthode de classes
class Greeter {
async sayHi() {
return 'Hi';
}
}
Qu'est-ce que await en javascript ?
Vous utilisez le mot-clé
async function display() {
let result = await sayHi();
console.log(result);
}
Dans cet exemple, le mot-clé
Notez que si vous utilisez l'opérateur
Comment gérer les erreurs dans une fonction asynchrone en javascript ?
Quand on est développeur javascript freelance il est important de bien gérer les erreurs. Si une promesse se résout, la promesse await
renvoie le résultat. Cependant, si la promesse est rejetée, la promesse await
lancera une erreur comme s'il y avait une instruction throw
.
Le code suivant :
async function getUser(userId) {
await Promise.reject(new Error('Invalid User Id'));
}
est la même chose que :
async function getUser(userId) {
throw new Error('Invalid User Id');
}
Dans le scénario réel, il faudra un certain temps pour que la promesse lance une erreur.
Vous pouvez attraper l'erreur en utilisant l'instruction try...catch
, de la même manière qu'une instruction throw
classique :
async function getUser(userId) {
try {
const user = await Promise.reject(new Error('Invalid User Id'));
} catch(error) {
console.log(error);
}
}
Il est possible d'attraper les erreurs causées par une ou plusieurs promesses :
async function showServiceCost() {
try {
let user = await getUser(100);
let services = await getServices(user);
let cost = await getServiceCost(services);
console.log(`The service cost is ${cost}`);
} catch(error) {
console.log(error);
}
}
Dans ce tutoriel, vous avez appris à utiliser le mot-clé JavaScript async / await
pour écrire du code asynchrone ressemblant à du code synchrone.
Questions fréquentes
Qu'est-ce que async en Javascript ?
En JavaScript, async est un mot-clé placé devant une fonction pour permettre à la fonction de renvoyer une promesse. JavaScript étant un langage synchrone, les fonctions asynchrones nous permettent d'écrire du code basé sur des promesses comme s'il était synchrone, mais sans bloquer le fil d'exécution, ce qui permet au code de s'exécuter de manière asynchrone.