‫Jonas : Écrivons maintenant
‫du code afin de mieux comprendre ce qui
‫se passe dans la boucle d'événements.
‫Donc, comme avant, pour commencer
‫la partie codage de cette section,
‫allez-y et récupérez les fichiers de
‫démarrage pour cette section, copiez-les quelque part,
‫puis ouvrez le projet dans votre éditeur de code.
‫Je l'ai donc ici sur le bureau et
‫dans mon VSCode, et tout ce que nous avons ici pour
‫commencer est ce fichier de test. txt, et donc je vais créer un nouveau fichier
‫ici, et je vais l'appeler la boucle d'événement. js.
‫Bon, maintenant il est en fait extrêmement difficile de simuler correctement la
‫boucle d'événement, car nous ne pouvons pas vraiment
‫mettre beaucoup de rappels dans toutes les files
‫d'attente de rappel dont
‫nous avons parlé tout à l'heure en même temps, n'est-ce pas.
‫Cette situation se produit lorsque,
‫par exemple, de nombreuses demandes arrivent dans
‫votre application, mais ici localement, c'est très difficile à reproduire.
‫Mais de toute façon, nous allons quand même faire des expériences
‫très intéressantes en utilisant certaines des choses que
‫nous avons apprises dans la dernière vidéo.
‫Et ce que nous allons faire,
‫c'est écrire un tas de lignes de code,
‫puis essayer de déterminer dans quel ordre elles doivent être
‫exécutées dans la boucle d'événements, et analyser si les
‫résultats que nous obtenons ont vraiment du sens.
‫Commençons donc par écrire un setTimeout, donc
‫essentiellement pour définir une minuterie, et j'utilise
‫une fonction de flèche ici, et
‫la seule chose
‫que je vais faire est de me connecter
‫à la console pour une chaîne, donc console. log, la minuterie 1 est terminée
‫et je veux que cela expire juste après zéro seconde.
‫D'accord, enregistrez-le, puis vous voyez qu'il a
‫en fait corrigé cette chaîne ici, il
‫a donc modifié ces guillemets et ajouté le point-virgule, et
‫c'est à cause de
‫l'extension Prettier que nous avons installée auparavant.
‫Maintenant, je ne vais pas le
‫configurer ici, car pour
‫ce petit exemple, ce n'est pas vraiment nécessaire, d'accord.
‫Donc, c'est régler une minuterie, alors
‫utilisons également setImmediate, alors rappelez-vous cela de la dernière vidéo.
‫Bon, maintenant je ne vais pas expliquer grand-chose
‫ici, pour l'instant écrivons ce
‫code, puis analysons ce qui se passe, d'accord.
‫Donc setImmediate, et tout comme l'autre minuteur, il reçoit
‫une fonction de rappel.
‫Et tout ce qu'on va faire c'est
‫en écrire un immédiat terminé, et celui-ci n'a pas le
‫temps, car ce n'est
‫pas nécessaire car comme son nom l'indique, c'est immédiat.
‫Ensuite, une autre chose que
‫nous voulons faire est de lire ce fichier ici,
‫puis de passer une fonction de rappel, d'accord, donc la
‫première chose est que nous devons exiger le bon module, donc FS, et
‫maintenant fs. readFile, et nous voulons un fichier texte. txt,
‫puis quelque chose se passe.
‫Et comme avant, disons simplement ici,
‫dans ce cas, les E/S sont terminées, d'accord.
‫Donc I/O parce que ce rappel
‫ici est en fait lié à une tâche d'E/S, qui obtient
‫en fait sa propre phase dans la boucle d'événement, n'est-ce pas.
‫Et puis enfin, ajoutons simplement une console. connectez-vous ici, en
‫disant bien, bonjour du code de niveau supérieur.
‫D'accord, et donc du code de niveau supérieur, car c'est en
‫fait le seul qui n'est à l'intérieur d'aucun rappel.
‫Donc, dans ce très petit exemple que nous avons pour l'instant, essayons
‫de comprendre ce qui devrait se passer en premier.
‫Eh bien, rappelez-vous que la première étape
‫lorsque nous chargeons un module est que son code de
‫niveau supérieur soit exécuté, nous devrions donc tout de
‫suite voir cette console. log ici, à droite,
‫seulement plus tard, nous devrions voir les autres journaux
‫provenant de ces autres rappels, car ces
‫rappels s'exécuteront en fait dans la boucle d'événements.
‫Essayons donc de voir si c'est
‫réellement le cas, puis analysons-le encore un peu mieux.
‫Donc, en ouvrant la console ici, et encore une
‫fois, je le fais en
‫utilisant le terminal, ou en fait dans la vue, donc ce terminal ici, d'accord.
‫Alors notez, la boucle d'événement. js, ou avant de le
‫faire, je dois corriger cette faute de frappe ici, il s'agit donc
‫d'un fichier de test, pas d'un fichier texte.
‫D'accord, mais maintenant nous sommes prêts à
‫exécuter cette commande, et les résultats sont arrivés, donc le
‫premier journal que nous avons ici est le bonjour du code
‫de niveau supérieur, et c'était prévu,
‫n'est-ce pas, car c'est un code qui est exécuté immédiatement.
‫Ensuite, nous avons ces trois sorties, mais elles ne sont en
‫fait pas dans un ordre particulier, et
‫c'est parce que ce code ici,
‫donc ce code, n'est en fait pas dans un cycle d'E/S,
‫donc il ne s'exécute pas à l'intérieur de la
‫boucle d'événement, car il ne s'exécute dans aucune fonction de rappel.
‫D'accord, donc sur votre ordinateur, vous pourriez en fait voir
‫ce journal ici avant
‫celui-ci, et celui-ci n'est que le
‫dernier parce que ce genre de gros fichier ici prend
‫un certain temps à lire, et donc
‫ce sera probablement toujours le dernier une.
‫Encore une fois, à ce stade, l'ordre de ces trois éléments n'a
‫rien à voir avec la boucle d'événement,
‫car ils ne s'exécutent
‫pas encore dans la boucle d'événement.
‫Pour cela, il va falloir les déplacer, ou
‫du moins déplacer ces deux ici, à l'intérieur d'une fonction de rappel.
‫Et donc, pour cela, nous allons utiliser celui-ci ici en fait.
‫Alors laissez-moi le mettre ici, et dites minuterie deux et minuterie deux ici,
‫ou deux immédiatement, et je vais également ajouter une autre minuterie ici, donc
‫la minuterie trois, et celle-ci
‫va fonctionner pendant trois secondes, soit 3000 millisecondes .
‫Essayons donc maintenant le résultat de celui-ci.
‫Mais avant de faire cela, réfléchissons en
‫fait à la raison pour laquelle, juste après l'exécution de tout
‫le code précédent, le programme s'est ensuite arrêté et est revenu à l'invite ici.
‫Alors rappelez-vous comment Node. js décide s'il doit
‫continuer à exécuter la boucle d'événement, eh bien, il le
‫fait en demandant s'il reste encore du temps en arrière-plan,
‫et si c'est le cas, il ne se terminera pas, et s'il
‫y a toujours une minuterie en attente, alors
‫ce n'est pas le cas va quitter le programme.
‫Mais s'il n'y en a pas,
‫ce qui était le cas dans le premier exemple ici, alors
‫il quitte immédiatement le programme, d'accord, mais maintenant nous avons
‫en fait une minuterie ici, donc celle-ci fonctionnera
‫pendant trois secondes, et essayons donc de comprendre ce
‫que se passe ici.
‫D'accord, vous voyez donc qu'il ne
‫se ferme pas, et seulement maintenant, une fois la minuterie
‫trois terminée, il a alors quitté l'application.
‫D'accord, voyons cela à nouveau, donc toutes ces
‫minuteries de journaux sont en cours d'exécution, la minuterie est
‫terminée, et donc elle a quitté l'application.
‫Maintenant à propos de ces résultats ici,
‫rendons cela un peu plus facile
‫à voir ici, et ajoutons juste un petit séparateur ici.
‫OK, nettoie ça, OK.
‫Donc, ces quatre sorties ici ne s'exécutaient pas
‫vraiment dans la boucle d'événement, mais
‫ces trois ici sortaient en
‫fait de la boucle d'événement, alors analysons maintenant ces résultats.
‫Maintenant, si vous vous
‫souvenez du diagramme de la conférence précédente, vous
‫aurez probablement pensé que la minuterie, donc la minuterie deux ici, devrait en
‫fait se terminer avant le setImmediate, car dans
‫le diagramme, elle est en fait apparue en premier
‫tout en haut de la boucle événementielle.
‫Nous devons donc définir ici le délai d'expiration avec
‫zéro, ce qui devrait être en quelque sorte le même que setImmediate, n'est-ce pas.
‫Alors pourquoi setImmediate
‫apparaît-il avant le setTimeout ?
‫Eh bien, il y a quelque chose que je
‫n'ai pas vraiment expliqué dans la dernière vidéo, parce que
‫je ne voulais pas rendre les choses encore plus confuses, et c'est que la
‫boucle d'événement attend en fait que des choses se produisent dans la phase de sondage.
‫Donc, dans cette phase où les rappels d'E/S sont gérés.
‫Ainsi, lorsque cette file d'attente de rappels est vide, ce qui
‫est le cas dans notre exemple fictif ici,
‫nous n'avons donc pas de rappels d'E/S,
‫tout ce que nous avons, ce sont ces minuteries, alors la
‫boucle d'événement attendra dans cette phase jusqu'à ce qu'il y ait un expiration minuteur.
‫Mais, si nous avons programmé un rappel à l'aide de setImmediate,
‫ce rappel sera en fait exécuté immédiatement
‫après la phase d'interrogation, et même
‫avant l'expiration des minuteries, s'il y en a une.
‫Et dans ce cas, le temporisateur expire immédiatement, donc
‫après zéro seconde, mais encore une fois, la
‫boucle d'événement attend en fait, elle s'arrête donc dans la phase d'interrogation.
‫Et donc ce rappel setImmediate
‫est en fait exécuté en premier, c'est donc toute
‫la raison pour laquelle nous avons ceci immédiatement après les minuteries.
‫D'accord, et je sais que cela semble très déroutant, et
‫je suis tout à fait d'accord, mais
‫c'est vraiment ainsi que Node. js fonctionne.
‫Et maintenant, rendons cela encore un peu plus confus et
‫ajoutons le processus. nextCochez dont nous
‫avons également parlé dans la dernière conférence.
‫Alors on dit processus. nextTick, puis comme avant, nous lui passons
‫simplement une fonction de rappel.
‫Et encore une fois, je veux juste me connecter
‫à la console, et je vais dire processus. suivantTick.
‫Alors que pensez-vous qu'il se passera dans ce cas?
‫Allez-y et faites une supposition, et une fois que vous êtes prêt,
‫vous pouvez alors exécuter ceci, alors faisons-le.
‫Enregistrez-le ici d'abord, exécutez-le, et c'est parti.
‫Les résultats sont donc à nouveau disponibles, et maintenant le
‫premier rappel qui a été exécuté était en fait cette fonction ici.
‫C'est pourquoi nous avons un processus. nextCochez à
‫droite dans le premier.
‫Alors pourquoi cette fonction de rappel du processus. suivantCocher le premier
‫de tous à être exécuté ?
‫Eh bien, rappelez-vous que nextTick fait
‫partie de la file d'attente des microtâches, qui sont
‫exécutées après chaque phase, donc pas seulement après un tick entier.
‫Et donc ce qui s'est passé ici, c'est
‫que cette fonction de rappel s'est en fait exécutée avant la phase où cette fonction
‫de rappel s'est exécutée ici, et la phase avant celle-ci, d'accord.
‫Maintenant, nextTick est en fait un nom trompeur, car un tick
‫est en fait une boucle entière, mais nextTick
‫se produit en fait avant la phase de boucle suivante,
‫et non le tick entier, c'est donc ce que je disais auparavant.
‫De l'autre côté, setImmediate vous ferait penser que
‫son rappel serait exécuté immédiatement, mais ce n'est
‫pas le cas, donc setImmediate est
‫exécuté une fois par
‫tick, tandis que nextTick est exécuté immédiatement.
‫Et donc leurs deux noms devraient en fait être intervertis.
‫Ils devraient être l'inverse, et cela
‫peut causer beaucoup de confusion,
‫il est donc préférable de toujours s'en tenir à l'un d'eux,
‫et c'est généralement setImmediate et non process. suivantTick.
‫Maintenant de toute façon, comme je l'ai mentionné dans
‫une dernière vidéo, ces mécanismes sont en fait plus pour des cas
‫d'utilisation assez avancés, c'est pourquoi
‫nous ne les utiliserons probablement pas dans notre projet.
‫Mais si vous voulez en savoir plus
‫sur eux, vous pouvez toujours lire la documentation officielle de Node.
‫D'accord, donc avec cela, nous avons simulé certains aspects
‫de la boucle d'événement, mais pour finir, je veux
‫juste introduire rapidement quelque chose sur le
‫pool de threads, et pour cela nous allons faire
‫une opération plus complexe qui sera en fait déchargée
‫sur le pool de threads, et regardez combien
‫de temps ces opérations prennent pour s'exécuter, et comment nous pouvons changer
‫la taille du pool
‫de threads dont nous avons parlé précédemment.
‫Nous allons donc utiliser un peu de
‫cryptographie ici pour crypter essentiellement un mot de passe.
‫C'est donc un nouveau package que nous
‫n'avions pas utilisé auparavant, et il s'appelle Crypto, mais j'ai mentionné
‫plus tôt qu'en fait, toutes les fonctions de ce package
‫seront automatiquement déchargées par la boucle d'événements vers le pool de
‫threads, et c'est ce que nous
‫je vais tester maintenant.
‫Et utilisons ceci maintenant, donc crypto. pb, nous allons donc utiliser une
‫fonction de cryptage appelée pbkdf2, donc un nom un peu bizarre,
‫et maintenant nous passons la chaîne secrète, qui disons simplement mot
‫de passe, puis nous avons besoin d'une chaîne pour résoudre les mots
‫de passe, et les implémentations ici n'a pas vraiment d'importance,
‫donc pour l'instant je ne vais pas entrer dans les détails
‫de la façon dont cela fonctionne, nous
‫allons le faire plus tard, d'accord, donc ici nous avons
‫juste besoin de la longueur de la
‫clé, donc ce nombre
‫ici est juste pour le nombre d'itérations, puis c'est la longueur de la
‫clé, et enfin l'algorithme, qui va
‫être utilisé pour crypter le mot de passe.
‫Ainsi, ces chiffres augmenteront
‫simplement le temps nécessaire au cryptage.
‫D'accord et enfin, il faut aussi une fonction de rappel, et tout ce que je vais faire
‫ici, c'est faire une autre console. log, et
‫dites simplement le mot de passe crypté.
‫Maintenant, pour les besoins de cette
‫démonstration, je veux en fait vous montrer combien de
‫temps chacune de ces opérations prend, donc ce
‫que nous allons faire est de définir une variable au début,
‫de la mettre à jour. maintenant, c'est donc la date actuelle en millisecondes,
‫et puis ici, tout ce que nous avons à faire est d'enregistrer non
‫seulement la chaîne, mais aussi la date. maintenant, qui sera la date à
‫ce stade en millisecondes, moins le début, et
‫cela nous donnera alors le nombre de millisecondes
‫qui se sont écoulées pour
‫faire ce calcul.
‫Bon, alors essayons-le, sauvegardons-le
‫et exécutons-le à nouveau, et vous voyez ici qu'il
‫a fallu 1855 millisecondes, donc presque
‫deux secondes pour crypter ce mot de passe.
‫D'accord, mais maintenant dupliquons ce code, ou en
‫fait je veux que quatre
‫instances de ceci vous montrent quelque chose.
‫Donc, si nous l'exécutons maintenant, cela devrait probablement prendre à peu près
‫le même temps, et oui c'est le cas,
‫donc c'était 1. 8 secondes,
‫maintenant il est 2. 2 secondes, ce qui est assez similaire.
‫D'accord, et rappelez-vous que je vous ai dit dans l'une
‫des conférences précédentes, que par défaut
‫la taille du pool de threads est de quatre,
‫donc il y a quatre threads qui font
‫le travail en même temps, et c'est
‫pourquoi ces quatre cryptages de mot de
‫passe prennent environ en même
‫temps et se produisent essentiellement tous en même temps.
‫Mais nous pouvons réellement changer cette taille de pool de threads.
‫Alors, laissez-moi vous montrer comment nous procédons, et nous le
‫faisons en disant processus. env, et c'est
‫une variable d'environnement, et encore une
‫fois nous en reparlerons plus tard, et
‫UV, qui signifie LibUV, la
‫taille du pool de threads, donc si nous la définissons sur un, nous
‫n'aurons qu'un seul thread dans notre pool de threads.
‫Alors essayons à nouveau, et voyons ce qui se passe maintenant.
‫Vous voyez donc qu'ils prennent tous beaucoup plus de temps à calculer.
‫En gros, ils sont calculés les uns après les autres.
‫Donc celui-ci le premier, puis celui-ci ici prend le double du
‫temps, et encore une fois c'est parce
‫que celui-ci ne peut commencer que dès que
‫le premier est terminé, et de même avec
‫le troisième et le quatrième.
‫Disons maintenant que nous
‫le changeons en deux, alors nous devrions
‫voir les deux premiers avec le même temps, et
‫exactement, les deux seconds également avec un temps similaire.
‫Donc ça a du sens, hein.
‫Juste pour terminer ici,
‫maintenant le même avec trois, donc ces trois ont
‫un temps similaire, puis le dernier.
‫D'accord, c'est donc ainsi que fonctionne le pool de threads, j'ai donc décidé non
‫seulement de me concentrer sur la boucle d'événements, mais aussi de
‫vous donner un aperçu, très rapide, du pool de threads et de la
‫façon dont nous pouvons modifier la taille du
‫pool de threads , d'accord, gardez à l'esprit
‫que ce code ici est
‫en fait toujours asynchrone, car nous avons transmis une fonction de rappel.
‫D'accord, et nous pourrions en fait utiliser la version synchrone,
‫mais cela bloquerait alors la boucle d'événements.
‫Tu veux voir ça ?
‫Alors permettez-moi de vous montrer ça aussi très rapidement,
‫donc celui-là n'était pas vraiment prévu, mais
‫faisons-le quand même, car c'est très intéressant
‫de voir ça je pense.
‫Bon, ça va fonctionner comme ça.
‫Nous utilisons à nouveau la version sync de la même fonction,
‫qui une note, est plusieurs fois disponible.
‫N'oubliez pas que nous avons la même chose pour le fichier
‫de lecture, nous avons donc le fichier de lecture,
‫qui accepte un rappel, et nous avons la synchronisation de fichier de
‫lecture, qui est la version synchrone qui n'accepte aucun rappel, donc comme ça.
‫Donc celui-ci chiffrera ensuite le mot
‫de passe, bloquera l'exécution du code, puis passera à la ligne
‫suivante, qui enregistrera alors ceci ici dans la console.
‫Alors dupliquons maintenant ceci ici.
‫C'était trop, débarrassez-vous de celui-ci ici, et maintenant
‫ces quatre cryptages de mot de passe ne fonctionneront plus
‫dans la boucle d'événement.
‫Et ainsi, ils ne seront plus déchargés dans le pool de threads.
‫D'accord, et maintenant, même si nous avons une taille de pool
‫de threads de quatre, voyons ce qui se passe.
‫Donc, vous voyez, ils se produisent complètement de manière synchrone.
‫Donc, l'un après l'autre, et ce qui est
‫encore pire, c'est que
‫toutes ces minuteries ici, même nextTick et
‫celle immédiate, n'apparaissent qu'après le cryptage des mots de passe.
‫Donc, cela bloquait vraiment toute l'exécution, même si ce minuteur
‫ici, par exemple celui-ci ici, était terminé après
‫zéro seconde, et celui-ci après trois
‫secondes, mais ils doivent tous
‫attendre sept secondes jusqu'à ce que tous
‫ces cryptages de mot de passe ici
‫soient enfin prêt, encore une fois parce qu'ils ne fonctionnaient pas à
‫l'intérieur de la boucle d'événement, mais ceux-ci l'étaient.
‫Et donc, ils travaillaient essentiellement en arrière-plan et ne
‫pouvaient être détectés par la
‫boucle d'événement que lorsqu'ils étaient prêts, juste après
‫ces quatre cryptages de mot de passe, donc
‫celui-ci était un autre excellent exemple de voir
‫le blocage de code et la boucle d'événement tout en action.
‫D'accord, donc c'était suffisant pour une conférence, j'espère que vous
‫l'avez trouvée intéressante, et
‫à bientôt pour la suivante.