JavaScript asynchrone
Asynchrone : fait référence à un environnement de communication où le client ne doit pas attendre une réponse immédiate pour continuer son traitement. Le fil d'exécution principal n'est pas bloqué en attendant une réponse.
JavaScript asynchrone
De nombreuses fonctionnalités des API Web utilisent désormais du code asynchrone pour s'exécuter, en particulier celles qui accèdent à un type de ressource ou le récupèrent à partir d'un périphérique externe, par exemple:
- en récupérant un fichier sur le réseau
- en accédant à une base de données et en renvoyant des données
- en accédant à un flux vidéo à partir d'une webcam
- en diffusant l'affichage vers un casque VR.
Fonctions de rappel asynchrones
Les callbacks asynchrones ou fonctions de rappels asynchrones sont des fonctions qui sont passées comme arguments lors de l'appel d'une fonction qui commencera à exécuter du code en arrière-plan. Lorsque le code d'arrière-plan a fini de s'exécuter, il appelle la fonction de rappel pour vous faire savoir que le travail est terminé. L'utilisation des callbacks est un peu démodée aujourd'hui, mais vous les verrez encore dans un certain nombre d'API plus anciennes encore couramment utilisées.
Promesses (Promises)
Les promesses sont un style de code asynchrone Javascript que vous verrez utilisé dans les API Web plus récentes.
L'objet Promise (pour « promesse ») est utilisé pour réaliser des traitements de façon asynchrone. Une promesse représente une valeur qui peut être disponible maintenant, dans le futur ou indiquée comme impossible à fournir. La "promesse" est donc de fournir une valeur ultérieurement ou de rejeter avec une raison (erreur), mais en tous les cas revenir à l'appelant plus tard.
Une Promise est dans un de ces états :
- pending (en attente) : état initial, la promesse n'est ni remplie, ni rompue ;
- fulfilled (tenue) : l'opération a réussi ;
- rejected (rompue) : l'opération a échoué ;
- settled (acquittée) : la promesse est tenue ou rompue mais elle n'est plus en attente.
Une promesse en attente peut être tenue avec une valeur ou rompue avec une raison (erreur). Quand on arrive à l'une des deux situations, les gestionnaires associés lors de l'appel de la méthode then sont alors appelés.

Gérer les opérations asynchrones avec élégance grâce aux promesses
Essentiellement, une promesse est un objet qui représente un état intermédiaire d'une opération - en fait, c'est une promesse qu'un résultat d'une certaine nature sera retourné à un moment donné dans le futur. Il n'y a aucune garantie du moment exact où l'opération se terminera, mais il est garanti que lorsque le résultat est disponible, ou que la promesse échoue, le code que vous fournissez sera exécuté afin de faire autre chose avec un résultat réussi, ou de gérer gracieusement un cas d'échec.
L'une des utilisations les plus courantes des promesses concerne les API web qui doivent accéder à des ressources externes.
Le problème des fonctions de rappel
Code désordonné et difficile à lire :
function choisirIngredients(callback, gererErreur) {
// Simulation d'une opération asynchrone
setTimeout(function() {
// Supposons que tout s'est bien passé et que nous avons les ingrédients
const ingredients = ['tomate', 'fromage', 'pepperoni'];
callback(ingredients);
}, 1000);
}
function placerLaCommande(ingredients, callback, gererErreur) {
// Simulation d'une opération asynchrone
setTimeout(function() {
// Supposons que tout s'est bien passé et que la commande est prête
const commande = `Commande de pizza avec ${ingredients.join(', ')}`;
callback(commande);
}, 1000);
}
function ramasserLaCommande(commande, callback, gererErreur) {
// Simulation d'une opération asynchrone
setTimeout(function() {
// Supposons que tout s'est bien passé et que la pizza est prête à être ramassée
const pizza = `Pizza prête: ${commande}`;
callback(pizza);
}, 1000);
}
function mangerLaPizza(pizza) {
console.log(pizza);
}
function gererErreur(erreur) {
console.log('Erreur : ', erreur);
}
// Appel enchaîné des fonctions de rappel - "callback hell"
choisirIngredients(function(ingredients) {
placerLaCommande(ingredients, function(commande) {
ramasserLaCommande(commande, function(pizza) {
mangerLaPizza(pizza);
}, gererErreur);
}, gererErreur);
}, gererErreur);
Créer une fonction qui retourne une promesse
Prenons par exemple l'extrait de code suivant. J'ai une fonction qui retourne un string, un affichage du résultat de la fonction à la console et un dernier affichage à la console.
Maintentant si la fonction maFonction est longue à exécuter et qu'on ne veux pas attendre le résultat pour continuer le traitement on peut transformer la fonction en fonction asynchrone qui retourne une promesse. Il faut que la fonction retourne un objet Promise. La promesse prend en paramêtre une fonction de rappel où on va indiquer avec si la promesse est tenue (resolve()) ou rompue (reject())
Chaîne de promesses
Amélioration de l'exemple plus haut (pizza) avec les promesses :
function placerLaCommande(ingredients) {
return new Promise((resolve, reject) => {
// Simulation d'une opération asynchrone
setTimeout(function() {
// Supposons que tout s'est bien passé et que la commande est prête
const commande = `Commande de pizza avec ${ingredients.join(', ')}`;
resolve(commande);
}, 1000);
});
}
[..]
choisirIngredients()
.then(function(ingredients) {
console.log('Ingrédients choisis : ', ingredients);
return placerLaCommande(ingredients);
})
.then(function(commande) {
console.log('Commande placée : ', commande);
return ramasserLaCommande(commande);
})
.then(function(pizza) {
console.log('Pizza ramassée : ', pizza);
mangerLaPizza(pizza);
})
.catch(gererErreur);
Vidéo explicative sur callback vs Promise (Bro Code)
https://www.youtube.com/watch?v=NOzi4wBHn0o
Async / Await - approche la plus récente et élégante pour l'asynchrone en JavaScript
On peut attendre le résultat d'une fonction asynchrone qui retourne une promesse à l'aide de await. Dans ce cas on va ajouter l'instruction async à la fonction asynchrone et await juste devant son appel.
Quand la promesse est rejetée une exception est levée et on peut la capturer avec un bloc try...catch.
Vidéo (suite) explicative sur async/await (Bro Code)
https://www.youtube.com/watch?v=9j1dZwFEJ-c