balises (séparées par des espaces) : minuteries JavaScript
J'ai récemment examiné les principes d'Ajax à cette époque , j'ai vu un article étranger qui expliquait le principe de fonctionnement du minuteur JavaScript, ce qui m'a aidé à bien comprendre le mode de fonctionnement monothread de js. Traduisez-le ici pour votre référence, adresse d'origine.
Texte de traduction
Fondamentalement parlant, il est très important de comprendre comment fonctionnent les minuteries JavaScript. Habituellement, js se comporte dans un seul thread. Examinons d'abord les trois fonctions qui peuvent construire et faire fonctionner des minuteries.
- 启动单个定时器,在延迟后调用指定的功能。该函数返回一个唯一的ID,该Id可以用于取消定时器 var id = setTimeout(fn, delay); - 类似setTimeout但不断地调用函数(每次都有延迟),直到它被取消,类似于定时任务。同上也返回唯一ID用于取消定时器 var id = setInterval(fn, delay); - 接受计时器ID(由上述任一功能返回)并停止触发计时器回调。 clearInterval(id); clearTimeout(id);
Pour comprendre le fonctionnement interne des minuteries, nous devons explorer un concept important : il n'est pas garanti que les délais des minuteries soient exacts. Étant donné que tout le JavaScript du navigateur s'exécute sur un seul thread, les événements asynchrones (tels que les clics de souris et les minuteries) ne s'exécutent que lorsqu'ils peuvent être exécutés. Ceci est mieux démontré à l'aide d'un diagramme, comme celui-ci :
Il y a beaucoup d'informations à comprendre dans ce diagramme, et le comprendre complètement vous donnera une meilleure compréhension de l'asynchrone. JavaScript La façon dont fonctionne l'exécution. Ce graphique est unidimensionnel : verticalement, nous avons le temps (horloge murale) en millisecondes. La case bleue indique la partie de JavaScript en cours d'exécution. Par exemple, l'exécution du premier bloc JavaScript prend environ 18 ms, un clic de souris sur le bloc prend environ 11 ms, et ainsi de suite.
Étant donné que JavaScript ne peut exécuter qu'un seul morceau de code à la fois (en raison de sa nature monothread), chaque bloc de code « bloque » la progression d'autres événements asynchrones. Cela signifie que lorsqu'un événement asynchrone se produit (comme un clic de souris, le déclenchement d'un minuteur ou la fin d'une requête XMLHttpRequest), il est mis en file d'attente pour une exécution ultérieure (la manière dont cette mise en file d'attente se produit dépend du navigateur). Les navigateurs varient, voici un bref explication).
Tout d'abord, dans le premier bloc de JavaScript, démarrez deux minuteries : 10 ms setTimeout et 10 ms setInterval. En raison de l'endroit et du moment où le minuteur démarre, il se déclenche avant que nous ayons réellement terminé le premier bloc de code. Mais notez qu'il ne sera pas exécuté immédiatement (il ne peut pas le faire à cause des threads) mais sera mis en file d'attente pour être exécuté au prochain moment disponible.
De plus, dans le premier bloc JavaScript, on voit le clic de souris. Le rappel JavaScript associé à l'événement de clic de souris (nous ne savons jamais quand l'utilisateur effectue une action, il est donc considéré comme asynchrone) ne peut pas être exécuté immédiatement, donc, comme le minuteur initial, il est mis en file d'attente pour être exécuté ultérieurement.
Immédiatement après que le bloc initial de JavaScript soit terminé, le navigateur en cours d'exécution demande : Quelles tâches sont dans la file d'attente en attente d'exécution ? Dans ce cas, le gestionnaire de clics de souris et le rappel du minuteur attendent. Le navigateur en sélectionne ensuite un (rappel par clic de souris) et l'exécute immédiatement. Le minuteur attendra la prochaine fois qu'il sera retiré de la file d'attente pour être exécuté.
Notez que lorsque le gestionnaire de clic de souris s'exécute, le premier rappel d'intervalle est exécuté. Comme un minuteur, son gestionnaire est mis en file d'attente pour une exécution ultérieure. Cependant, veuillez noter que lorsque l'intervalle est à nouveau déclenché (lors de l'exécution du programme de minuterie), le rappel d'intervalle d'Interval est ignoré (Note du traducteur : je ne le comprends pas très bien ici, veuillez laisser un message pour échanger des conseils. Est-ce car il y a déjà un intervalle en file d'attente ? Si vous souhaitez appeler un rappel d'intervalle lors de l'exécution d'une grande partie de code, les rappels d'intervalle seront ajoutés consécutivement à la file d'attente des tâches, sans délai entre eux. Les navigateurs se contentent souvent d'accéder à la file d'attente et de récupérer les tâches jusqu'à ce qu'il n'y ait plus d'autres tâches dans la file d'attente.
En fait, nous pouvons voir que le rappel du troisième intervalle se déclenche pendant que l'intervalle lui-même est en cours d'exécution. Cela nous montre un fait important : les intervalles ne se soucient pas de ce qui est en cours d'exécution, ils font la queue sans discernement.
Enfin, une fois l'exécution du deuxième rappel d'intervalle terminée, nous pouvons voir que le moteur JavaScript n'a aucune tâche à effectuer. Cela signifie que le navigateur attend maintenant qu'un nouvel événement asynchrone se produise. Lorsque l'intervalle se déclenche à nouveau, il est à la position 50 ms. Cependant, cette fois, aucun programme n’est en cours d’exécution, il est donc déclenché immédiatement.
Regardons un exemple pour mieux illustrer la différence entre setTimeout et setInterval.
setTimeout(function(){ /* Some long block of code... */ setTimeout(arguments.callee, 10); }, 10); setInterval(function(){ /* Some long block of code... */}, 10);
Ces deux morceaux de code peuvent sembler fonctionnellement équivalents à première vue, mais ils ne le sont pas. Il convient de noter que le code setTimeout a toujours un délai d'au moins 10 ms après l'exécution du rappel précédent (cela peut finir par être supérieur, mais jamais inférieur à 10 ms), tandis que setInterval essaie à chaque fois pendant cette longue exécution de code, un rappel est exécuté. toutes les 10 ms (Note du traducteur : on peut comprendre que lors de l'exécution de ce code long, une tâche sera ajoutée à la file d'attente toutes les 10 ms, sans intervalle entre les deux).
Nous avons beaucoup appris ici, passons en revue :
Le moteur JavaScript n'a qu'un seul thread, ce qui oblige les événements asynchrones à être mis en file d'attente pour leur exécution.
setTimeout et setInterval sont fondamentalement différents dans la façon dont ils exécutent le code asynchrone.
Si le minuteur ne peut pas s'exécuter immédiatement, il sera retardé jusqu'au prochain point d'exécution possible (qui dépassera le délai requis).
Si le temps d'exécution du programme de rappel dans setInterval est suffisamment long (dépasse le délai spécifié), l'intervalle peut être exécuté sans délai (Note du traducteur : car un autre rappel sera ajouté lorsqu'un rappel n'a pas fini de s'exécuter).
Tout cela constitue une connaissance très importante pour comprendre le fonctionnement du moteur JavaScript, en particulier le grand nombre d'événements asynchrones qui se produisent, et jette les bases de la création de code d'application avancé.
Recommandations associées :
Principe de fonctionnement de la minuterie Javascript
À propos de l'analyse du principe de la minuterie en JavaScript
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!