L'asynchronisme en JavaScript
Published: 2023-11-06 16:18:17

JavaScript est souvent qualifié de _single-threaded_ (à un seul thread) en raison de la manière dont il gère l'exécution des opérations. 🧵 

Cela signifie que le code s'exécute dans un seul processus à la fois, de manière séquentielle.

Pour éviter de bloquer le thread principal et permettre des opérations non-blocantes, JavaScript utilise des mécanismes comme les fonctions de rappel (callbacks), les promesses et l'API async/await. Ces approches permettent de gérer des opérations asynchrones de manière plus efficace. 🚀

Voici des exemples d'utilisation de chacune de ces approches :

## Les `callbacks`, ou fonctions de rappel

```javascript
function téléchargerDonnées(url, callback) {
  // Simuler une opération asynchrone
  setTimeout(function () {
    let données = "Données téléchargées depuis " + url;
    callback(données);
  }, 1000); // Simule un délai de 1 seconde
}

téléchargerDonnées("http://exemple.com/données", function (résultat) {
  console.log(résultat);
});
```

Cette approche est efficace, mais lorsque de nombreuses fonctions de rappel (callbacks) sont utilisées, le code devient très vite difficile à lire et complexe. On surnomme cette situation le _callback hell_.

```javascript
téléchargerDonnées("http://exemple.com/premiere-donnee", function (donnée1) {
  // Première opération asynchrone
  console.log(donnée1);

  téléchargerDonnées("http://exemple.com/deuxieme-donnee", function (donnée2) {
    // Deuxième opération asynchrone imbriquée
    console.log(donnée2);

    téléchargerDonnées("http://exemple.com/troisieme-donnee", function (donnée3) {
      // Troisième opération asynchrone encore plus imbriquée
      console.log(donnée3);

      // ... et ainsi de suite
    });
  });
});
```

Comme on peut voir dans l'exemple ci-dessus, de nombreuses fonctions de rappel sont imbriquées les unes dans les autres, ce qui rend le code difficile à suivre et à maintenir. 😫 

Pour simplifier la gestion des opérations asynchrones et rendre le code plus lisible, JavaScript propose des alternatives telles que les promesses. Les promesses permettent de gérer ces opérations de manière plus linéaire et propre. 🌟

## Utilisation de promesses (Promises)

L'objet `Promise` représente une valeur qui n'est pas nécessairement connue au moment de la création de la promesse.

Une Promise peut avoir trois états :
 - `pending` (en attente) : état initial, la promesse n'est ni tenue, ni rompue
 - `fulfilled` (tenue) : l'opération a réussi
 - `rejected` (rompue) : l'opération a échoué.

[en savoir plus](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Promise)

On peut gérer la promesse quand elle est résolue avec le mot-clé `.then()` et gérer les erreurs potentielles avec `.catch()` 

```javascript
téléchargerDonnées("http://exemple.com/premiere-donnee")
  .then(function (donnée1) {
    console.log(donnée1);
    return téléchargerDonnées("http://exemple.com/deuxieme-donnee");
  })
  .then(function (donnée2) {
    console.log(donnée2);
    return téléchargerDonnées("http://exemple.com/troisieme-donnee");
  })
  .then(function (donnée3) {
    console.log(donnée3);
    // ...
  })
  .catch(function (erreur) {
    console.error(erreur);
  });
```

## L'API `async/await`

La dernière méthode pour gérer des opérations asynchrones est celle considérée la plus propre et la plus facile à gérer par beaucoup de développeurs.

En utilisant l'API async/await, vous pouvez déclarer une fonction comme asynchrone avec le mot-clé async. Cela permet d'attendre la résolution d'une promesse à l'aide de l'opérateur await, rendant le code plus lisible et fluide. 🌐

```javascript
async function afficherDonnées() {
  try {
    let résultat = await téléchargerDonnées("http://exemple.com/données");
    console.log(résultat);
  } catch (erreur) {
    console.error(erreur);
  }
}

afficherDonnées();
```

En utilisant `async/await`, le code devient plus expressif et plus proche de la manière dont nous pensons naturellement les opérations asynchrones. Cela facilite le développement et la maintenance des applications JavaScript tout en maintenant leur réactivité. 🚀😄

Cette syntaxe est fréquemment utilisée avec l'instruction `try...catch` pour gérer les erreurs éventuelles.

En résumé, JavaScript est "single-threaded" par nature, mais il utilise des mécanismes comme les promesses et l'API async/await pour gérer les opérations asynchrones de manière propre, évitant ainsi les problèmes de "callback hell" et offrant une meilleure expérience de développement. 🥳

Merci d'avoir lu cet article jusqu'au bout! Je t'invite à me laisser ton avis en commentaire, ou à me suivre sur [Twitter](https://twitter.com/claire_dochez) pour plus d'astuces JavaScript! 🚀👩‍💻👍