Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Joel Reis

21 février 2024

Min Read

Guide rapide des modèles asynchrones JavaScript

Des applications Web aux serveurs et aux applications mobiles, des petits programmes aux grands projets, JavaScript est partout. C'est le choix principal pour accueillir n'importe quel projet car, eh bien, nous sommes en 2020 et JS est un langage encore plus mature, soutenu par une énorme communauté.

Stack Overflow Trends (insights.stackoverflow.com)
blue arrow to the left
Imaginary Cloud logo

Écrire du code JavaScript asynchrone

En JavaScript, tout le code s'exécute de manière synchrone sur la boucle d'événements, qui exécute de manière séquentielle de petits morceaux de notre programme. Dans la boucle d'événements, chaque itération est appelée « cocher » et s'exécute jusqu'à ce que la file d'attente soit vide. Chaque morceau possède un « cocher » à traiter et une fois terminé, le suivant démarre. Pour les petites applications, cela suffit, mais à mesure que nous commençons à effectuer des opérations plus lourdes qui prennent plus de temps, comme accéder à une base de données ou récupérer des données sur Internet, nous avons besoin de meilleurs mécanismes pour les gérer.

blue arrow to the left
Imaginary Cloud logo

Modèles Javascript pour le développement frontal

Au fil des ans, des modèles et des bibliothèques sont apparus dans Écosystème JS pour gérer la programmation asynchrone, telle que les rappels, les événements, les promesses, les générateurs, async/wait, les web workers et les packages sur le registre NPM tels que async, bluebird, co ou RxJS.

En ce qui concerne les développeurs frontaux, nous devrons peut-être utiliser différents modèles pour résoudre les problèmes complexes du quotidien en fonction du framework sur lequel nous travaillons. Connaître les outils disponibles dans le monde JavaScript nous permet de choisir la meilleure solution pour chaque problème.

Vous vous demandez peut-être si ce guide est uniquement destiné au développement Web ? Non, la plupart de ces modèles sont utilisés dans tous les environnements et plates-formes JavaScript. Il est donc toujours utile pour tout développeur de savoir comment ils fonctionnent.

blue arrow to the left
Imaginary Cloud logo

Qu'est-ce qu'un rappel

En JavaScript, les fonctions sont des objets de première classe et rappel est juste une fonction qui est passée en argument à une autre fonction. Également connue sous le nom de fonctions d'ordre supérieur, la fonction de rappel doit être invoquée chaque fois que le travail asynchrone est terminé.

Comme les callbacks ne sont que des fonctions, ils sont pris en charge par tous les environnements qui exécutent JavaScript, de nos navigateurs aux serveurs qui exécutent Node.js. Simple mais puissant, ce modèle est fondamental en asynchronie. Cependant, elle présente également des inconvénients.

Lorsque les projets commencent à prendre de l'ampleur et que nous devons commencer à créer du code plus complexe, il devient plus difficile d'implémenter des solutions génériques dans nos programmes, ce qui les rend plus difficiles à lire et à gérer. Lorsque cela se produit, nous commençons à avoir la forme pyramidale de `}) `similaire à ce que nous pouvons voir dans l'exemple suivant.

Ceci est généralement connu sous le nom « L'enfer du rappel ».

Cependant, le pire que nous puissions avoir avec les callbacks est l'inversion du contrôle. Si cela se produit, nous donnons le contrôle de la séquence du programme à d'autres parties, ce qui rend la tâche difficile (voire impossible !) pour le tester correctement.

blue arrow to the left
Imaginary Cloud logo

Comment fonctionnent les événements JavaScript ?

Une architecture pilotée par les événements peut également être utilisée pour écrire du code javascript asynchrone. Cette architecture consiste à avoir un émetteur d'événements avec un écouteur d'événements correspondant, qui envoie des événements lorsque le code asynchrone est terminé. L'envoi de différents types d'événements permet d'avoir des callbacks différents pour chaque type d'auditeurs. Un exemple de base et une partie très importante du développement du front-end est la demande de données sur Internet. Pour y parvenir, nous pourrions utiliser Requête HTTP XML objet très utilisé dans la programmation AJAX.


L'objet XMLHttpRequest possède déjà des écouteurs d'événements définis pour gérer le flux de requêtes, il suffit donc d'en tirer parti. Mais ce modèle contient beaucoup de code standard, car nous pourrions ajouter et supprimer des écouteurs en fonction des différents types d'événements dont nous avons besoin. Cela fonctionne parfaitement sur une petite page Web, mais dès que la complexité et les fonctionnalités augmentent, elle commence à être gonflée et fastidieuse à gérer, donc de meilleures abstractions sont nécessaires !

blue arrow to the left
Imaginary Cloud logo

Qu'est-ce qu'une promesse

Promesses sont plus difficiles à maîtriser, mais résolvent le problème de l'inversion du contrôle. Ils sont un peu plus lents que les rappels, mais en retour, nous obtenons une grande fiabilité.

Nous pouvons toujours être sûrs qu'une Promise sera résolue ou rejetée car elle constitue un « emballage » autour d'une valeur qui n'existe peut-être pas encore. Les promesses sont un mécanisme fiable qui permet également d'exprimer le code asynchrone de manière plus séquentielle. Ils peuvent avoir au plus une valeur de résolution, ce qui signifie qu'une promesse doit toujours être résolue ou rejetée.

C'est ainsi qu'ils résolvent l'inversion de contrôle. Non pas en supprimant les rappels, mais en créant un mécanisme sur le wrapper qui gère ce problème.

Nous pouvons enchaîner plusieurs promesses sur notre code sans forcer un nouveau niveau d'indentation après chacune d'elles, en utilisant .then ().

Les promesses offrent plus de fonctionnalités, comme, par exemple, le Promets-moi tout () et Promesse. race () par rapport aux derniers ajouts d'API Promesse. Tout est réglé () et Promets.any (). Les applications Web frontales étant de plus en plus complexes, nous avons besoin de mécanismes plus nombreux et de meilleure qualité.

Cela améliore la lisibilité du code, ainsi que la maintenabilité du programme, mais tout n'est pas parfait. Comme cette fonctionnalité se situe au niveau du framework, le comportement de plusieurs implémentations peut varier, sans compter les frais généraux liés au temps et à la mémoire.

blue arrow to the left
Imaginary Cloud logo

Générateurs en JavaScript

Générateurs ont été introduites sur ECMAScript 2015 et sont des fonctions dans lesquelles nous pouvons utiliser et contrôler l'itérateur, ce qui signifie que les fonctions peuvent être suspendues et reprises à tout moment. Il s'agit d'un outil puissant lorsque nous voulons obtenir chaque valeur uniquement lorsque nous en avons besoin, au lieu de les obtenir toutes en même temps. Cela est possible avec l'ajout du mot rendement vers JavaScript.


Nous pouvons voir dans cet exemple que pour chaque suivant () nous recevons un objet avec la valeur et un indicateur indiquant si les fonctions du générateur ont pris fin. Mais les générateurs peuvent également être utilisés pour contrôler les flux asynchrones en conjugaison avec d'autres bibliothèques, comme dans co ou saga Redux, dont je parlerai plus en détail plus loin.

blue arrow to the left
Imaginary Cloud logo

Comment utiliser un modèle Async/Await

Enfin, ES2017 a introduit fonctions asynchrones ce qui facilite grandement l'écriture et la lecture de code asynchrone en JavaScript !

Ils sont beaucoup plus propres que les derniers modèles abordés, et le retour d'une fonction asynchrone est une promesse ! C'est très puissant parce que nous avons la bonté des deux mondes. Comme nous l'avons vu précédemment, les promesses sont le choix le plus sûr lorsqu'il s'agit d'opérations asynchrones complexes, mais elles ne sont pas si faciles à lire et à maîtriser en tant que code async/wait.

Un inconvénient est qu'il a besoin d'un transpilation outil, comme Babel, car Async/Await est toujours le sucre syntaxique du code des promesses.

Étant donné que le résultat est une promesse et peut être résolu/rejeté, il est important d'encapsuler notre code d'attente dans un try/catch. De cette façon, nous pouvons gérer correctement les erreurs sur notre code asynchrone.

blue arrow to the left
Imaginary Cloud logo

Travailleurs Web en tant que tâches d'arrière-plan asynchrones

À l'aide de web-workers, il est possible d'exécuter des scripts et des fonctions sur un thread différent, en exécutant du code dans des tâches d'arrière-plan asynchrones. Cela n'affectera pas la convivialité de l'interface utilisateur et peut envoyer des données entre les travailleurs et le thread principal.

Le service worker de nos navigateurs est très utilisé sur les applications Web progressives. Cela consiste à enregistrer un travailleur Web pour notre site Web et à décider quels fichiers peuvent être mis en cache ou non, afin d'accélérer l'utilisation de l'application. De plus, si l'utilisateur est hors ligne, certaines fonctionnalités seront toujours disponibles. Ils peuvent également être utilisés pour effectuer des opérations lourdes sans geler l'interface utilisateur ou le thread JS principal.

Bibliothèques NPM

Plusieurs autres bibliothèques tentent de résoudre ces problèmes, chacune utilisant ses propres techniques. Vous trouverez quelques exemples à l'avance :

Asynchrone: cette bibliothèque est idéale pour travailler avec les rappels en essayant de résoudre certains problèmes qu'ils contiennent, tout en éliminant le problème de l'enfer des rappels ! Dans les dernières implémentations, il est également possible d'utiliser du code Async/wait.


Merle bleu: une implémentation très performante de Promises qui inclut également de nombreuses fonctionnalités supplémentaires telles que l'annulation, l'itération et Promisify ! Ce dernier est un wrapper autour des fonctions fonctionnant avec des rappels, renvoyant une Promise pour ces fonctions.


co: contrôlez les flux asynchrones à l'aide de générateurs. Cette bibliothèque est un environnement d'exécution autour de générateurs, combinant le mot clé yield avec des promesses, exécutant le résultat du générateur et le renvoyant sous forme d'objet de promesse.


La saga Redux: Une bibliothèque frontale pour la pile React/Redux. Il s'agit d'un intergiciel Redux visant à rendre les effets secondaires des applications plus efficaces et plus faciles à gérer, car ils peuvent être démarrés ou annulés par des actions Redux. Cette implémentation fait un usage intensif de générateurs pour récupérer des données sur Internet et appliquer les effets secondaires nécessaires sur notre site Web.


RxJS: Il s'agit d'un modèle utilisé sur les applications Angular et c'est un modèle réactif. Nous créons un observable auquel nous pouvons nous abonner et attendre les modifications dont nous serons informés. En utilisant ce modèle, il est possible d'annuler des abonnements et de chaîner des observables, par exemple.

Quels modèles asynchrones devons-nous utiliser ?

Pour les projets simples, les rappels constituent le moyen le plus simple et le plus simple de gérer les flux asynchrones. Sur les projets plus importants avec une configuration appropriée, je choisirais le modèle async/wait, car l'asynchronicité est facile à lire, permet une gestion naturelle des erreurs et il n'y a pas de pyramide de la mort.

C'est le type de sucre syntaxique dont nous avons besoin dans notre travail, pour nous permettre d'écrire un programme plus lisible et plus facile à gérer.

Most popular programming languages in GitHub 2014 - 2019 (octoverse.github.com)

Comme le montre l'image ci-dessus, JavaScript reste le langage le plus utilisé sur GitHub, au même titre que sa communauté dynamique.

C'est notre premier choix pour gérer les flux asynchrones, mais il existe d'autres moyens d'obtenir les mêmes résultats que ceux décrits dans ce guide. Dans l'ensemble, c'est à vous de choisir ce qui convient le mieux à vos besoins.

Ready for a UX Audit? Book a free call

Vous avez trouvé cet article utile ? Ceux-ci vous plairont peut-être aussi !

blue arrow to the left
Imaginary Cloud logo
blue arrow to the left
Imaginary Cloud logo
Joel Reis
Joel Reis

Développeur full stack et passionné de JavaScript. Un front-end de premier ordre, c'est mon truc où j'aime expérimenter de nouvelles choses. Pêcheur en kayak, brasseur et buveur de bière !

Read more posts by this author

People who read this post, also found these interesting:

arrow left
arrow to the right
Dropdown caret icon