Sauter à un chapitre clé
Comprendre la boucle d'événements en Javascript
La boucle d'événements JavaScript, à la base, est un mécanisme qui gère l'exécution de plusieurs threads, ce qui permet à JavaScript de paraître multithread au niveau de la machine, même si en réalité, JavaScript n'est pas multithread.
Qu'est-ce qu'une boucle d'événements en JavaScript ?
JavaScript est un langage monotâche, ce qui signifie qu'il traite une tâche à la fois tout en gardant les autres dans une file d'attente. Le concept de ce système de file d'attente nous amène à la boucle d'événements JavaScript. C'est un cycle d'un processus constamment en cours d'exécution permettant de traiter les rappels asynchrones de manière synchronisée.Imagine que c'est comme un restaurant très fréquenté. La cuisine (le moteur de JavaScript) ne peut traiter qu'une seule commande (fonction/tâche) à la fois, tandis que les autres commandes sont mises en file d'attente. La boucle d'événements est le système du restaurant qui vérifie si la cuisine est prête à prendre une autre commande.
Les fonctions de base de la boucle d'événements JavaScript
La boucle d'événements JavaScript possède plusieurs fonctions cruciales. Les voici :- Elle maintient une file d'attente de tâches.
- Elle supervise la pile d'exécution et vérifie sa disponibilité pour exécuter une nouvelle tâche.
- Lorsque la pile d'exécution est vide, elle autorise l'exécution de la première tâche de la file d'attente.
- Et il répète ce processus indéfiniment, ce qui permet à Javascript de gérer plusieurs tâches et rappels de façon transparente.
Comment fonctionne la boucle d'événements JavaScript ?
Le fonctionnement de la boucle d'événements JavaScript se comprend mieux en quatre étapes :- Création du cadre de pile : La fonction main() (ou contexte global) est créée et poussée dans le Stack Frame actuel.
- Exécution initiale du code : Le navigateur commence à lire et à exécuter le code ligne par ligne.
- File d'attente de rappel : Les fonctions asynchrones (comme setTimeout) sont envoyées à une API Web et poussées dans la file d'attente des rappels une fois qu'elles sont terminées.
- Vérification de la boucle d'événements : Lorsque le cadre de pile est vide, ce qui signifie que tout le code a été lu, la boucle d'événements vérifie la file d'attente de rappel. Si elle n'est pas vide, les fonctions sont mises en file d'attente et poussées sur le Stack Frame pour être exécutées.
Le moteur d'exécution JavaScript contient une file d'attente de messages, qui est une liste de messages à traiter. Chaque message est associé à une fonction qui est appelée pour traiter le message. À un moment donné de la boucle d'événements, le système d'exécution commence à traiter les messages de la file d'attente, en commençant par le plus ancien. Pour traiter le message, la fonction associée est appelée avec le message comme paramètre d'entrée. Dès que la pile est à nouveau vide, une vérification est effectuée pour voir s'il existe une fonction de temporisation en attente et, si c'est le cas, cette fonction (telle qu'une fonction retardée de setTimeout) est exécutée, ce qui démarre l'exécution d'un nouveau message. Ainsi, même si JavaScript est monotâche, il peut toujours faire de la concurrence grâce à la boucle événementielle et aux API du navigateur ou de Node.js.
function main() { console.log('Hi') ; setTimeout(function cb1() { console.log('cb1') ; }, 5000) ; console.log('Bye') ; } main() ; // Sortie // "Hi" // "Bye" // "cb1" après 5 secondesDans l'exemple de code ci-dessus, nous appelons d'abord la fonction main. Elle comporte trois étapes - tout d'abord, elle enregistre "Hi" sur la console, puis elle fixe un délai d'attente de 5 secondes, après quoi elle enregistrera "cb1", et enfin, elle enregistre "Bye". Comme JavaScript n'a qu'une seule pile d'appels, il traite ces opérations l'une après l'autre. Tu verras donc d'abord "Hi" enregistré, puis "Bye", et enfin, après que cinq secondes se seront écoulées, "cb1". Même si la fonction setTimeout a été appelée en second, elle n'empêche pas le reste du code de s'exécuter - ce comportement non bloquant est dû à la boucle événementielle.
Exploration d'exemples de boucles d'événements en JavaScript
Comprendre le fonctionnement des boucles d'événements en JavaScript peut parfois s'avérer une tâche décourageante. Pour aider à démystifier les concepts, explorons quelques exemples. Nous aborderons cela en deux étapes - un exemple de boucle d'événements simple, puis un autre plus complexe.Exemple simple de boucle d'événements en JavaScript
Imagine un code JavaScript très simple qui imprime une chaîne de caractères après un certain délai. Voici un exemple d'un tel code en action :setTimeout(function() { console.log("Hello after 3 seconds") ; }, 3000) ;Lorsque ce morceau de code s'exécute, la console reste vide et attend 3 secondes avant que "Hello after 3 seconds"', ne soit imprimée. Ce délai est dû à la nature du mécanisme de la boucle d'événements JavaScript. Voici comment JavaScript y parvient :
- Une fois que la fonction setTimeout est rencontrée dans le code, puisqu'il s'agit d'une API Web, elle est envoyée hors de la pile d'appels vers une API Web de minuterie.
- Cette minuterie compte pendant 3000 millisecondes.
- Une fois que la minuterie a fini de compter, elle place la fonction spécifiée dans le setTimeout dans une file d'attente de rappel.
- La boucle d'événement, qui fonctionnait indéfiniment, vérifie si la pile d'appels est vide.
- Une fois qu'elle est vide, elle retire la fonction de la file d'attente de rappel et la place sur la pile d'appels pour qu'elle soit exécutée.
Exemple de boucle événementielle complexe en JavaScript
Considérons maintenant un scénario plus complexe. Imaginons un script qui définit deux délais d'attente - un qui s'imprime immédiatement et un autre qui s'imprime après une seconde :setTimeout(function() { console.log("Hello") ; }, 0) ; setTimeout(function() { console.log("Hello after 1 second") ; }, 1000) ;Dans ce scénario, bien que la première fonction setTimeout ait un délai d'attente de zéro milliseconde, elle ne s'imprime pas immédiatement. Au lieu de cela, elle est déplacée dans l'environnement de l'API Web et, une fois le délai écoulé, elle est placée dans la file d'attente des rappels. Pendant ce temps, le moteur JavaScript voit la deuxième fonction setTimeout et passe à celle-ci. Une fois que les deux fonctions setTimeout terminées reviennent des API Web, elles sont envoyées dans la file d'attente des rappels. L'ordre d'exécution des fonctions dans la file d'attente des rappels est déterminé par leur ordre d'achèvement. Enfin, la boucle d'événements surveille en permanence la pile d'appels et la file d'attente des rappels. Lorsque la pile d'appels est vide et que la file d'attente de rappels contient des fonctions exécutables, elle les place dans la pile pour qu'elles soient exécutées. Par conséquent, dans un premier temps, "Hello after 1 second" sera imprimé, puis "Hello" sera imprimé. Tout au long de ce processus, la boucle d'événements s'assure en priorité que la pile d'appels est vidée le plus rapidement possible avant de recevoir tout message entrant de la file d'attente des messages. C'est pourquoi, même lorsqu'il est réglé sur zéro seconde, le rappel de la première fonction setTimeout ne s'exécute pas immédiatement. Elle attend la fin du script entier, ce qui montre que la boucle d'événements accorde une plus grande priorité à la pile d'appels qu'aux messages en file d'attente. Cette interaction entre la pile d'appels, l'API Web, la file d'attente des rappels et la boucle d'événements est la quintessence du fonctionnement de l'environnement d'exécution JavaScript et est essentielle pour comprendre comment fonctionne le code asynchrone en JavaScript.
Boucle d'événements et pile d'appels en JavaScript
JavaScript est un langage à un seul thread, mais grâce à l'interaction de l'Event Loop et de la Call Stack, il peut gérer plusieurs tâches avec un haut degré d'efficacité.Comprendre la relation entre la pile d'appels JavaScript et la boucle d'événements
L'environnement d'exécution JavaScript comporte deux éléments clés : la pile d'appels et la boucle d'événements. Ils sont responsables de la façon dont JavaScript gère l'exécution du code. Nous allons nous pencher sur leur relation et leur fonctionnement. La pile d'appels est une structure de données qui enregistre le contexte d'exécution des fonctions. Lorsqu'une fonction JavaScript est appelée, elle est placée, ou "poussée", dans la pile d'appels. Elle est ensuite exécutée par le moteur JavaScript. Une fois l'exécution de la fonction terminée, elle est "sortie" de la pile. S'il y a une fonction à l'intérieur d'une fonction, la fonction interne est poussée sur la pile et devient la fonction en cours d'exécution. D'autre part, la boucle d'événements est un processus continu qui vérifie si la pile d'appels est vide. Si la pile d'appels est vide et que la file d'attente de rappels ne l'est pas, il pousse la première fonction de rappel de la file d'attente de rappels sur la pile d'appels. L'importance de la pile d'appels pour la boucle d'événements est double :- La pile d'appels détermine en grande partie le moment où la boucle d'événements y insère de nouvelles fonctions de rappel. En d'autres termes, ce n'est que lorsque la pile est vide que la boucle d'événements déplace les fonctions de la file d'attente des rappels vers la pile d'appels.
- Lorsqu'une fonction est en cours d'exécution, la pile d'appels est "occupée" et la boucle d'événements n'en ajoutera pas d'autres. En d'autres termes, si une fonction prend trop de temps à s'exécuter, elle peut bloquer la pile d'appels et empêcher l'exécution d'autres codes.
() { console.log('Function One') ; function functionTwo() { console.log('Function Two') ; } functionTwo() ; } functionOne() ; // Sortie : // Function One // Function TwoLes fonctions functionOne et functionTwo sont ajoutées à la pile d'appels lorsqu'elles sont appelées, et retirées une fois qu'elles sont terminées. Comme functionTwo a été appelée à l'intérieur de functionOne, elle a été ajoutée au sommet de la pile et est devenue la fonction en cours d'exécution.
Comment la pile d'appels JavaScript influence-t-elle la boucle d'événements ?
Le comportement de la pile d'appels JavaScript a un impact significatif sur la boucle d'événements. En raison de la nature monotâche de JavaScript, la pile d'appels ne peut contenir qu'un seul contexte d'exécution de fonction à la fois, ce qui influence le moment et la manière dont l'Event Loop traite les tâches. L'Event Loop vérifie constamment si la pile d'appels est vide. Si c'est le cas, et si des fonctions de rappel attendent dans la file d'attente de rappel, ces fonctions sont poussées sur la pile. Cependant, si la pile d'appels n'est pas vide, ces rappels doivent attendre, même si la fonction en cours d'exécution prend beaucoup de temps à se terminer. Un bloc de code dont l'exécution prend beaucoup de temps, comme une grande boucle ou une fonction nécessitant beaucoup de calculs, peut interrompre le flux de fonctions de la file d'attente des rappels vers la pile d'appels. Ce phénomène, connu sous le nom de blocage de la boucle événementielle, est un problème de performance courant qui doit être évité pour une exécution fluide du code JavaScript.for (let i = 0 ; i < 1000000000 ; i++) { console.log('Blocking Code') ; } setTimeout(function() { console.log("Non-blocking Code") ; }, 0) ;Dans l'exemple ci-dessus, la boucle peut bloquer la pile d'appels au cours de son exécution. Le message "Code non bloquant" ne sera imprimé qu'après la fin de la boucle for, même si le délai setTimeout est fixé à 0 seconde. Cela montre comment l'état "occupé" de la pile d'appels affecte la boucle d'événements. En conclusion, le comportement de la pile d'appels influe considérablement sur l'efficacité de la boucle d'événements, ce qui a un impact sur les performances perçues d'une application JavaScript. En comprenant cette relation, tu peux écrire un code JavaScript meilleur et plus efficace.
Mécanisme de la boucle d'événements en JavaScript
La boucle d'événements est au cœur de toute application JavaScript, responsable de la gestion de l'exécution des scripts et du rendu dans les navigateurs. Pour apprécier pleinement son importance et comprendre comment le code JavaScript s'exécute de manière asynchrone malgré le fait qu'il soit monotâche, nous allons approfondir le mécanisme de l'Event Loop et sa synchronisation.Décomposition du mécanisme JavaScript de la boucle d'événements
Au cœur de son mécanisme, la boucle d'événements gère l'exécution de plusieurs morceaux de ton code JavaScript. Chaque morceau de ce code peut être une fonction, un script ou un événement déclenché par un utilisateur ou une API Web. Pour comprendre le mécanisme, démêlons les composantes du modèle de concurrence de JavaScript, qui sont des éléments essentiels de l'environnement d'exécution JavaScript : lapile d'appels : C'est l'endroit où ton code JavaScript est exécuté, une opération à la fois. Lorsqu'une ligne de code est prête à être exécutée, elle est ajoutée (ou "poussée") dans la pile d'appels. Et lorsqu'elle a fini de s'exécuter, elle est retirée (ou "sortie") de la pile.API Web : Il s'agit de bibliothèques intégrées fournies par le navigateur, pour les opérations que le langage JavaScript lui-même ne gère pas. Lorsqu'une opération de l'API Web (telle qu'une requête de recherche ou un minuteur) se termine, elle ajoute un message à la file d'attente des rappels. File d'attente des rappels : Une fois qu'une fonction a terminé son opération dans les API Web, elle est ajoutée à cette file d'attente. Les fonctions sont mises en file d'attente dans l'ordre dans lequel elles ont terminé leur exécution dans les API Web. Enfin, voici ce que fait la boucle d'événements: - Elle vérifie si une opération est en attente sur la pile. Si la pile est vide, elle déplace la première opération de la file d'attente des rappels vers la pile - Ce processus se poursuit sans cesse, en veillant à ce que chaque fonction exécutée obtienne le temps CPU dont elle a besoin, et en s'assurant que les interactions de l'utilisateur ne restent pas bloquées trop longtemps dans la file d'attente des rappels. Ainsi, la boucle d'événements maintient l'équilibre et la nature non bloquante de ton code JavaScript.Comprendre la chronologie du mécanisme JavaScript de la boucle d'événements
Il est essentiel de comprendre la chronologie du mécanisme de la boucle d'événements pour écrire un code JavaScript efficace et non bloquant. Nous allons nous pencher sur les principaux facteurs de synchronisation :- Zéro délai : L'une des principales idées fausses concernant les fonctions de minuterie JavaScript telles que setTimeout() est que le paramètre de temps représente un temps d'attente exact pour l'exécution de sa fonction de rappel. Or, ce n'est pas le cas.
setTimeout(() => { console.log('Hello World') ; }, 0) ;Le code ci-dessus ne garantit pas que 'Hello World' sera imprimé exactement après 0 milliseconde. En effet, le timing ne tient pas compte du temps nécessaire à la pile d'appels, à la boucle d'événements et à la file d'attente des rappels pour traiter d'autres opérations. Lorsque la boucle d'événements retire la fonction de rappel de la file d'attente de rappels et la place sur la pile d'appels, elle ne le fait que lorsque la pile est vide. Cela peut créer un retard.
- Ordre d'exécution :dans la boucle d'événements, l'ordre d'exécution ne suit pas nécessairement l'ordre de la pile d'appels. Il est plutôt dicté par l'ordre des opérations dans la file d'attente des rappels. Lorsque les opérations envoyées aux API Web se terminent, elles sont ajoutées à la file d'attente des rappels. La boucle d'événements récupère les opérations de la file d'attente de rappels dans l'ordre où elles ont été ajoutées.
) => { console.log('First') ; }, 2000) ; setTimeout(() => { console.log('Second') ; }, 1000) ;Bien que 'First' apparaisse avant 'Second' dans le code et donc dans la pile d'appels en premier, 'Second' sera imprimé avant 'First'. Cela est dû au fait que la boucle d'événements placera 'Second' dans la file d'attente des rappels avant 'First', car son délai d'attente est plus court. La compréhension de ces nuances et facteurs temporels peut considérablement améliorer tes compétences en JavaScript. Tout au long du processus, la boucle d'événements assure l'exécution harmonieuse des tâches, en maintenant la concurrence dans l'environnement monotâche de JavaScript.
La boucle d'événements JavaScript dans la programmation asynchrone
Même si JavaScript est intrinsèquement monofilaire, sa capacité à gérer des tâches de manière asynchrone est l'une de ses caractéristiques les plus frappantes. La magie qui se cache derrière cette caractéristique est principalement due à la boucle d'événements Javascript.Rôle de la boucle d'événements Javascript dans la programmation asynchrone
Le respect que suscite JavaScript en tant que langage robuste et polyvalent est dû en grande partie à sa capacité à fonctionner de manière transparente sur différents supports tels que les navigateurs et les serveurs, et cela est dû en grande partie à son comportement asynchrone. La capacité asynchrone est due à la fonctionnalité de la boucle d'événements, basée dans l'environnement d'exécution de JavaScript, où elle travaille aux côtés de structures telles que la pile d'appels et la file d'attente de rappels. La programmation asynchrone permet à JavaScript d'exécuter des tâches en dehors du flux principal du programme sans bloquer l'exécution du code suivant. Cette nature non bloquante garantit que ton programme ne reste pas bloqué, attendant que des tâches telles que des demandes de réseau ou des minuteries se terminent, alors que d'autres codes pourraient être en cours d'exécution. C'est là que le rôle de la boucle d'événements devient crucial. La tâche de la boucle d'événements est de surveiller constamment la pile d'appels et la file d'attente des rappels. Si la pile d'appels est vide, elle prend la première tâche de la file d'attente de rappels et la place dans la pile d'appels pour qu'elle soit exécutée. Ce processus simple est ce qui permet un comportement asynchrone en JavaScript. Toute fonction qui doit être exécutée de manière asynchrone, comme setTimeout ou fetch, est envoyée à un module de l'API Web (comme la minuterie ou le module de requête HTTP, intégré dans le navigateur). Une fois que l'opération de l'API Web est terminée, elle pousse une fonction de rappel dans la file d'attente des rappels. La boucle d'événements veille ensuite à ce que ces fonctions de rappel soient renvoyées à la pile d'appels lorsqu'elle est prête pour d'autres tâches.Comprendre la programmation asynchrone grâce à des exemples de boucles d'événements en Javascript
Comprendre la boucle d'événements à l'aide d'exemples de code pratiques peut aider à cimenter le concept. Explorons quelques exemples pour montrer comment la boucle d'événements gère le code JavaScript asynchrone. Dans l'exemple simple ci-dessous, une fonction de minuterie s'exécute de manière asynchrone, ce qui ne bloque pas l'exécution du log 'After setTimeout'.console.log('Before setTimeout') ; setTimeout(() => { console.log('Inside setTimeout') ; }, 0) ; console.log('After setTimeout') ;Dans la sortie, tu remarqueras que 'Inside setTimeout' est imprimé en dernier, malgré un délai de 0 millisecondes. Cela est dû à la boucle d'événements. Bien que 'Inside setTimeout' fasse partie de la fonction setTimeout, il est transmis à l'API Web, ce qui libère la pile d'appels. La pile d'appels passe à l'exécution de 'After setTimeout'. Ce n'est que lorsque la pile d'appels est libérée et que la minuterie est terminée que la boucle d'événements déplace "Inside setTimeout" de la file d'attente des rappels vers la pile d'appels pour exécution. Comprendre le rôle de la boucle d'événements dans ce scénario explique pourquoi le JavaScript asynchrone fonctionne comme il le fait. Même si la fonction setTimeOut semble devoir afficher "Inside setTimeout" avant "After setTimeout", ce n'est pas le cas. Examinons un autre exemple :
console.log('Before fetch request') ; fetch('https://jsonplaceholder.typicode.com/posts') .then(() => console.log('Fetch successful') .catch(() => console.log('Fetch failed')) ; console.log('After fetch request') ;Dans ce cas, la demande de fetch est traitée de manière asynchrone, de la même manière que la fonction setTimeout. Lors de l'appel de fetch, il est déchargé vers une API Web (le module de requêtes HTTP), ce qui permet à la pile d'appels de passer à l'étape "Après la requête fetch". La fonction de rappel '.then()' n'est placée dans la file d'attente des fonctions de rappel qu'une fois l'opération de recherche terminée. Même s'il faut du temps pour que la ressource soit extraite de l'URL, le reste du programme continue à fonctionner sans attendre la fin de la demande d'extraction. La boucle d'événements, une fois de plus, gère cela en douceur. À partir de ces exemples, le rôle évolutif de la boucle d'événements JavaScript devient clair : garder ton code JavaScript non bloquant et fonctionnant en douceur en gérant efficacement la pile d'appels et la file d'attente de rappels autour d'opérations asynchrones.
Boucle d'événements JavaScript - Principaux enseignements
- Boucle d'événements Javascript : Un processus en cours d'exécution continue qui vérifie si la pile d'appels est vide. Si c'est le cas et que la file d'attente des rappels contient des fonctions prêtes à être exécutées, il les place dans la pile d'appels pour qu'elles soient exécutées.
- Pile d'appels : Une structure de données qui enregistre le contexte d'exécution des fonctions en JavaScript. Les fonctions sont "poussées" dans la pile d'appels pour être exécutées et "sorties" une fois qu'elles sont terminées.
- File d'attente de rappel : Les fonctions qui ont terminé leur opération dans les API Web sont ajoutées à cette file d'attente où elles attendent d'être exécutées.
- Comportement non bloquant : Obtenu grâce à la boucle d'événement, qui permet à JavaScript de poursuivre d'autres tâches sans attendre la fin d'une tâche qui prend beaucoup de temps (comme setTimeout).
- API Web : Bibliothèques intégrées fournies par le navigateur qui gèrent les opérations non prises en charge par le langage JavaScript. Lorsqu'une opération se termine, elle ajoute un message à la file d'attente des rappels.
Apprends avec 15 fiches de Boucle d'événements Javascript dans l'application gratuite StudySmarter
Tu as déjà un compte ? Connecte-toi
Questions fréquemment posées en Boucle d'événements Javascript
À propos de StudySmarter
StudySmarter est une entreprise de technologie éducative mondialement reconnue, offrant une plateforme d'apprentissage holistique conçue pour les étudiants de tous âges et de tous niveaux éducatifs. Notre plateforme fournit un soutien à l'apprentissage pour une large gamme de sujets, y compris les STEM, les sciences sociales et les langues, et aide également les étudiants à réussir divers tests et examens dans le monde entier, tels que le GCSE, le A Level, le SAT, l'ACT, l'Abitur, et plus encore. Nous proposons une bibliothèque étendue de matériels d'apprentissage, y compris des flashcards interactives, des solutions de manuels scolaires complètes et des explications détaillées. La technologie de pointe et les outils que nous fournissons aident les étudiants à créer leurs propres matériels d'apprentissage. Le contenu de StudySmarter est non seulement vérifié par des experts, mais également régulièrement mis à jour pour garantir l'exactitude et la pertinence.
En savoir plus