• Assurez la sécurité des applications de la bonne manière! Détectez, protégez, surveillez, accélérez et plus encore…
  • Bien que cela puisse nécessiter une compréhension approfondie de langages tels que C ++ et C pour écrire du code de production à grande échelle, JavaScript peut souvent être écrit avec juste une compréhension de base de ce qui peut être fait avec le langage.

    Les concepts, comme passer des rappels à des fonctions ou écrire du code asynchrone, ne sont souvent pas si difficiles à implémenter, ce qui rend la plupart des développeurs JavaScript moins soucieux de ce qui se passe sous le capot. Ils ne se soucient tout simplement pas de comprendre les complexités qui en ont été profondément abstraites par la langue.

    En tant que développeur JavaScript, il devient de plus en plus important de comprendre ce qui se passe réellement sous le capot et comment la plupart de ces complexités abstraites de nous fonctionnent vraiment. Cela nous aide à prendre des décisions plus éclairées, ce qui peut, à son tour, améliorer considérablement les performances de notre code.

    Cet article se concentre sur l'un des concepts ou termes très importants mais rarement compris en JavaScript. le BOUCLE D'ÉVÉNEMENT!. 

    L'écriture de code asynchrone ne peut pas être évitée en JavaScript, mais pourquoi un code exécuté de manière asynchrone signifie-t-il vraiment? c'est à dire La boucle d'événement

    Avant de comprendre comment fonctionne la boucle d'événements, nous devons d'abord comprendre ce qu'est JavaScript lui-même et comment il fonctionne!

    Qu'est-ce que JavaScript?

    Avant de continuer, j'aimerais que nous revenions à l'essentiel. Qu'est-ce que JavaScript? Nous pourrions définir JavaScript comme;

    JavaScript est un langage simultané, asynchrone, interprété, à thread unique, de haut niveau.

    Attends, qu'est-ce que c'est? Une définition livresque? 🤔

    Décomposons-le!

    Les mots clés ici concernant cet article sont monotrou, non bloquant, simultané, et asynchrone.

    Fil unique

    Un thread d'exécution est la plus petite séquence d'instructions programmées pouvant être gérée indépendamment par un ordonnanceur. Un langage de programmation est monothread, ce qui signifie qu'il ne peut effectuer qu'une seule tâche ou opération à la fois. Cela signifie qu'il exécuterait un processus entier du début à la fin sans que le thread ne soit interrompu ou arrêté.

    Contrairement aux langages multithreads où plusieurs processus peuvent être exécutés simultanément sur plusieurs threads sans se bloquer.

    Comment JavaScript peut-il être monothread et non bloquant en même temps?

    Mais que signifie le blocage?

    Non bloquant

    Il n'y a pas de définition unique du blocage; cela signifie simplement des choses qui fonctionnent lentement sur le fil. Donc, non bloquant signifie des choses qui ne sont pas lentes sur le fil.

    Mais attendez, ai-je dit que JavaScript fonctionnait sur un seul thread? Et je l'ai également dit non bloquant, ce qui signifie que la tâche s'exécute rapidement sur la pile d'appels? Mais comment??? Et quand nous exécutons des minuteries? Boucles?

    Se détendre! Nous découvririons dans un peu.

    Concurrent

    La concurrence signifie que le code est exécuté simultanément par plus d'un thread.

    Ok, les choses deviennent vraiment bizarre maintenant, comment JavaScript peut-il être monothread et être simultané en même temps? c'est à dire, exécuter son code avec plus d'un thread?

    asynchrones

    La programmation asynchrone signifie que le code s'exécute dans une boucle d'événements. Lorsqu'il y a une opération de blocage, l'événement est lancé. Le code de blocage continue de s'exécuter sans bloquer le thread d'exécution principal. Lorsque le code de blocage termine son exécution, il met en file d'attente le résultat des opérations de blocage et les repousse dans la pile.

    Mais JavaScript a un seul thread? Qu'est-ce qui exécute alors ce code de blocage tout en laissant les autres codes du thread s'exécuter?

    Avant de continuer, récapitulons ce qui précède.

    • JavaScript est monothread
    • JavaScript n'est pas bloquant, c'est-à-dire que les processus lents ne bloquent pas son exécution
    • JavaScript est simultané, c'est-à-dire qu'il exécute son code dans plus d'un thread en même temps
    • JavaScript est asynchrone, c'est-à-dire qu'il exécute du code de blocage ailleurs.

    Mais ce qui précède ne correspond pas exactement, comment un langage à thread unique peut-il être non bloquant, simultané et asynchrone?

    Allons un peu plus loin, passons aux moteurs d'exécution JavaScript, V8, peut-être qu'il a des threads cachés dont nous ne sommes pas conscients.

    Moteur V8

    Le moteur V8 est un moteur d'exécution d'assemblage Web Open source hautes performances pour JavaScript écrit en C ++ par Google. La plupart des navigateurs exécutent JavaScript à l'aide du moteur V8, et même l'environnement d'exécution populaire de node js l'utilise également.

    En anglais simple, le V8 est un programme C ++, qui reçoit du code JavaScript, le compile et l'exécute.

    Le V8 fait deux choses principales;

    • Allocation de mémoire de tas
    • Contexte d'exécution de la pile d'appels

    Malheureusement, nos soupçons étaient erronés. Le V8 n'a qu'une seule pile d'appels, pensez à la pile d'appels comme au thread.

    Un thread === une pile d'appels === une exécution à la fois.

    Image - Hacker Noon

    Étant donné que V8 n'a qu'une seule pile d'appels, comment JavaScript s'exécute-t-il simultanément et de manière asynchrone sans bloquer le thread d'exécution principal?

    Essayons de le découvrir en écrivant un code asynchrone simple mais courant et analysons-le ensemble.

    JavaScript exécute chaque code ligne par ligne, l'un après l'autre (monothread). Comme prévu, la première ligne est imprimée dans la console ici, mais pourquoi la dernière ligne est-elle imprimée avant le code de délai? Pourquoi le processus d'exécution n'attend-il pas le code de délai d'attente (blocage) avant de continuer à exécuter la dernière ligne?

    Un autre thread semble nous avoir aidés à exécuter ce délai car nous sommes à peu près sûrs qu'un thread ne peut exécuter qu'une seule tâche à tout moment.

    Jetons un aperçu de la Code source V8 pour un moment.

    Attends quoi??!!! Il n'y a pas de fonctions de minuterie dans V8, pas de DOM? Pas d'événements? Pas d'AJAX?…. Yeeeeessss !!!

    Les événements, DOM, minuteries, etc. ne font pas partie de l'implémentation principale de JavaScript, JavaScript est strictement conforme aux spécifications des scripts Ecma et diverses versions de celui-ci sont souvent référencées selon ses spécifications de scripts Ecma (ES X).

    Workflow d'exécution

    Les événements, les minuteries, les requêtes Ajax sont tous fournis côté client par les navigateurs et sont souvent appelés API Web. Ce sont eux qui permettent au JavaScript à thread unique d'être non bloquant, simultané et asynchrone! Mais comment?

    Il existe trois sections principales pour le flux de travail d'exécution de tout programme JavaScript, la pile d'appels, l'API Web et la file d'attente des tâches.

    La pile d'appels

    Une pile est une structure de données dans laquelle le dernier élément ajouté est toujours le premier à être retiré de la pile, vous pouvez la considérer comme une pile d'une plaque dans laquelle seule la première plaque qui a été la dernière ajoutée peut être supprimée en premier. Une pile d'appels n'est rien d'autre qu'une structure de données de pile où les tâches ou le code sont exécutés en conséquence.

    Prenons l'exemple ci-dessous;

    Source - https://youtu.be/8aGhZQkoFbQ

    Lorsque vous appelez la fonction printSquare() , il est poussé sur la pile d'appels, le printSquare() function appelle la fonction square (). le square() est poussée sur la pile et appelle également la fonction multiply() fonction. La fonction de multiplication est poussée sur la pile. Puisque la fonction de multiplication retourne et est la dernière chose qui a été poussée vers la pile, elle est résolue en premier et est supprimée de la pile, suivie de square() fonction puis le printSquare() la fonction.

    L'API Web

    C'est là que le code qui n'est pas géré par le moteur V8 est exécuté pour ne pas «bloquer» le thread d'exécution principal. Lorsque la pile d'appels rencontre une fonction API Web, le processus est immédiatement transféré à l'API Web, où il est en cours d'exécution et libère la pile d'appels pour effectuer d'autres opérations pendant son exécution.

    Revenons à notre setTimeout exemple ci-dessus;

    Lorsque nous exécutons le code, la première ligne console.log est poussée vers la pile et nous obtenons notre sortie presque immédiatement, en arrivant au délai d'attente, les minuteries sont gérées par le navigateur et ne font pas partie de l'implémentation principale de V8, elles sont poussées à l'API Web à la place, libérant la pile afin qu'elle puisse effectuer d'autres opérations.

    Pendant que le délai d'expiration est toujours en cours d'exécution, la pile passe à la ligne d'action suivante et exécute le dernier console.log, ce qui explique pourquoi nous obtenons ce résultat avant la sortie du minuteur. Une fois la minuterie terminée, quelque chose se passe. La console.log in then timer apparaît comme par magie dans la pile d'appels à nouveau!

    Comment?

    La boucle d'événement

    Avant de discuter de la boucle d'événements, passons d'abord par la fonction de la file d'attente des tâches.

    Revenons à notre exemple de délai d'expiration, une fois que l'API Web a terminé d'exécuter la tâche, elle ne la renvoie pas automatiquement à la pile d'appels. Il va au File d'attente des tâches. 

    Une file d'attente est une structure de données qui fonctionne sur le principe du premier entré, premier sorti, de sorte que lorsque les tâches sont poussées dans la file d'attente, elles sortent dans le même ordre. Les tâches qui ont été exécutées par les API Web, qui sont poussées vers la file d'attente des tâches, puis reviennent à la pile d'appels pour obtenir leur résultat imprimé.

    Mais attendez. QUEL EST LE HECK LA BOUCLE D'ÉVÉNEMENT ???

    Source - https://youtu.be/8aGhZQkoFbQ

    La boucle d'événements est un processus qui attend que la pile d'appels soit effacée avant de pousser les rappels de la file d'attente de tâches vers la pile d'appels. Une fois la pile vide, la boucle d'événements se déclenche et vérifie la file d'attente des tâches pour les rappels disponibles. S'il y en a, il le pousse vers la pile d'appels, attend que la pile d'appels soit à nouveau vide et répète le même processus.

    Source - https://www.quora.com/How-does-an-event-loop-work/answer/Timothy-Maxwell

    Le diagramme ci-dessus illustre le flux de travail de base entre la boucle d'événements et la file d'attente de tâches.

    Conclusion

    Bien qu'il s'agisse d'une introduction très basique, le concept de programmation asynchrone en JavaScript donne suffisamment d'informations pour comprendre clairement ce qui se passe sous le capot et comment JavaScript est capable de fonctionner simultanément et de manière asynchrone avec un seul thread.

    JavaScript est toujours à la demande, et si vous êtes curieux d'apprendre, je vous conseillerais de vérifier ceci Cours Udemy.