Comprendre async/await en Javascript

Les mots-clés async et await permettent une simplification de l'utilisation des promesses en Javascript, mais quel est leur fonctionnement ?

Article publié le 11/04/2022, dernière mise à jour le 02/10/2023

Pour comprendre cet article, vous devez connaitre les bases des Promise en Javascript. Si ce n'est pas le cas, consultez mon précédent article !

Pour rappel, une promesse est une sorte de callback générique pour le retours de fonctions asynchrones. C'est l'équivalent d'une fonction avec seulement deux possibilité de sortie : Le succès (resolve), ou l'échec (reject).

Voici un exemple de gestion de promesse sans async/await :

function example(url){
  fetch(url).then((response)=>{
    return response.json();
  }).then((data)=>{
    console.log(data);
  }).catch((e)=>{
    alert(e);
  });
}

Et la version avec async/await :

async function(url){
  try {
    const response = await fetch(url);
    const data = await response.json();
    console.log(data);
  } catch(e){
    alert(e);
  }
}

En regardant les exemples au-dessus, on comprends vite l'intérêt d'utiliser async/await : la lisibilité/simplicité du code.

Et plus les chaines de promesses sont imbriquées, plus la simplification du code est grande !

Mais au final,quels sont les rôles exacts de chacun des mots-clés ? C'est ce que nous allons voir !

Async

La directive async est utilisée pour spécifier que la fonction en question possède un fonctionnement asynchrone.

Plus précisément, lorsque vous ajoutez le mot-clé "async" devant une fonction, vous forcez cette fonction à retourner une promesse, quel que soit le contenu de cette fonction.

Exemple :

async function example1(){
  return 0;
}

est l'équivalent de

function example2(){
  return new Promise((resolve, reject)=>{
    resolve(0);
  });
}

L'exemple utilisé ci-dessus n'a pas d'intérêt fonctionnel, mais démontre l'effet de la directive

Même avec une fonction synchrone, on force la fonction dans un mode asynchrone en enrobant son contenu dans une promesse.

D'ailleurs, vous pouvez vérifiez en examinant le retour de la fonction async une fois exécutée :

console.log(example1());
// $> Promise { 0 }

Mais pourquoi forcer une fonction à retourner une promesse ?

Pour pouvoir utiliser une directive qui fonctionne UNIQUEMENT avec des promesses :  le mot-clé "await" !

Await

Cette directive permet simplement de capturer une promesse en cours de traitement, de bloquer l'exécution en attendant la résolution de cette dernière.

Une fois résolue, la valeur reçue sera retournée, pourra être stockée (ou non) et l'exécution pourra continuer. Si la promesse est rejetée, alors l'erreur sera envoyée au prochain bloc de capture des exceptions (catch).

En résumé, await permet de passer d'un fonctionnement asynchrone vers un fonctionnement synchrone.

Comme pour async, voici un code équivalent à await :

// avec await
try {
  const user = await signup(...);
  return user;
} catch(e){
  ...
}

sans await

try {
  const user, error;
  signup.then((data)=>{
  	user = data;
  }).catch((e)=>{
  	error = e;
  });
  while(!user && !error){
    //waiting loop
  }
  return user;
} catch(e){
  ...
}

Comme l'exemple précédent, celui-ci est purement théorique

Vous l'aurez compris, l'impact sur le code est de bloquer l'exécution et éviter la gestion d'opération en parallèle, lorsque ces dernières n'ont pas besoin de l'être.

Mais il faut faire attention, si vous rendez synchrone des opérations qui auraient pu se dérouler en parallèle, alors vous pourrez ralentir votre exécution de manière significative, comme expliqué dans cet article :

À noter qu'async/await est supporté à 92% par les navigateurs actuels, et n'est pas supporté par Internet Explorer.


Rafael De Nadai sur Unsplash

Vous avez terminé l'article ?

Commentaires (0)

pour laisser un commentaire

Aucun commentaire pour l'instant