Maison > Article > interface Web > Explication détaillée du mécanisme multithread du navigateur
Cette fois, je vais vous apporter une explication détaillée du mécanisme multi-thread du navigateur. Quelles sont les précautions lors de l'utilisation du mécanisme multi-thread du navigateur. Voici des cas pratiques, jetons un coup d'oeil.
Avant de parler, tout le monde sait que js est basé sur un seul thread, et ce fil est le moteur js du navigateur.
Tout d’abord, jetons un coup d’œil aux fils de discussion que tout le monde utilise dans son navigateur.
Si nous voulons effectuer certaines opérations fastidieuses, comme le chargement d'une grande image, nous pouvons avoir besoin d'une barre de progression pour laisser l'utilisateur attendre pendant tout le processus d'attente. js sera bloqué et le code suivant ne pourra pas s'exécuter normalement, ce qui peut réduire considérablement l'expérience utilisateur. À l'heure actuelle, nous nous attendons à avoir un thread de travail pour gérer ces opérations fastidieuses. C'était fondamentalement impossible à réaliser à l'ère du HTML traditionnel, mais maintenant, nous avons ce qu'on appelle un travailleur. C'est une classe en js, et il suffit d'en créer une instance pour l'utiliser.
var worker = new Worker(js file path);
Construisez les paramètres de la fonction et renseignez le chemin de votre fichier js. Ce fichier js sera exécuté dans un thread nouvellement ouvert du navigateur, contrairement au js d'origine. le moteur. Les threads ne sont pas affectés.
Donc, puisqu'ils ne s'affectent pas, comment les deux threads communiquent-ils entre eux ? La réponse est en fait déjà dans le code, c'est-à-dire les deux fonctions onPostMessage et onmessage. ) êtes-vous Les données à transmettre, et onmessage est une fonction de rappel Ce n'est que lorsque les données sont reçues que onmessage a un paramètre caché, qui est event.data. pour obtenir le transmis Les données entrantes sont utilisées pour mettre à jour le thread principal.
JavaScript setTimeout et setInterval sont deux méthodes qui peuvent facilement tromper les sentiments des autres, car nous pensons souvent que lorsqu'elles sont appelées, elles seront exécutées de la manière établie, je pense que beaucoup de gens. en suis profondément conscient. J'ai le même sentiment, par exemple,
De même, je n'ai aucun doute sur le fait que la méthode callbackFunction de setInterval est exécutée immédiatement toutes les 100 millisecondes ![javascript] voir l'impression en copie standard ?
pensez que la méthode de salutation dans setTimeout sera exécutée immédiatement, car cela n'est pas dit de nulle part, mais le document de l'API JavaScript définit clairement la signification du deuxième paramètre comme le nombre de millisecondes après quoi la méthode de rappel sera exécutée. Elle est définie ici sur 0 milliseconde, bien sûr. Elle a été exécutée immédiatement.
setTimeout( function() { alert('Bonjour !'); } , 0);
setInterval( callbackFunction , 100);
Mais alors que l'expérience de développement d'applications JavaScript continue de croître et de s'enrichir, un jour, j'ai trouvé un morceau de code étrange et je n'ai pas pu le comprendre :
[javascript]Jusqu'au dernier jour, vous avez accidentellement écrit un mauvais morceau de code :voir l'impression en copie standard ?
p.onclick = function(){
Puisqu'il est exécuté après 0 milliseconde, pourquoi utiliser setTimeout ? À ce moment-là, la ferme conviction a commencé à vaciller.- setTimeout( function(){document .getElementById('inputField').focus();}, 0);
- }
[ javascript]voir la copie brute imprimée ?
setTimeout( function(){ while(true){} } , 100
setTimeout( function(){ alert('Bonjour ! '); ); } , 200);
setInterval( callbackFunction , 200);
La première ligne de code entre dans une boucle infinie , mais bientôt vous constaterez que les deuxième et troisième lignes ne correspondent pas à vos attentes, le message d'accueil d'alerte n'est pas apparu et il n'y a aucune nouvelle de callbackFunction
En ce moment, vous êtes complètement confus ! C'est difficile à accepter, car le processus de changement des cognitions établies de longue date pour accepter de nouvelles idées est douloureux, mais les faits sont sous nos yeux et la recherche de la vérité sur JavaScript ne s'arrêtera pas à cause de la douleur. Fil JavaScript et voyage d'exploration du minuteur !
Ouvrez les nuages et voyez le clair de lune
La raison principale de tous les malentendus ci-dessus est : croire inconsciemment qu'il existe plusieurs moteurs JavaScript. Le fil est en cours d'exécution et la fonction de rappel de minuterie de JavaScript est exécutée de manière asynchrone.
En fait, JavaScript utilise une méthode aveuglante pour tromper nos yeux la plupart du temps. Le rétroéclairage ici doit clarifier un fait :
.Le moteur JavaScript s'exécute dans un seul thread. Le navigateur n'a qu'un seul thread exécutant le programme JavaScript à tout moment.
Le moteur JavaScript utilise Single- Le fonctionnement threadé est également significatif. Le fonctionnement monothread n'a pas à se soucier de problèmes complexes tels que la synchronisation des threads, et le problème est simplifié.
Alors, comment un moteur JavaScript monothread coopère-t-il avec le noyau du navigateur pour gérer ces minuteries et répondre aux événements du navigateur ? Qu'en est-il ?
Ce qui suit est une brève explication basée sur la méthode de traitement du noyau du navigateur.
L'implémentation du noyau du navigateur permet à plusieurs threads de s'exécuter de manière asynchrone. d'autres sous le contrôle du noyau pour maintenir la synchronisation.Si un certain navigateur L'implémentation du noyau du navigateur a au moins trois threads résidents : le thread du moteur JavaScript, le thread de rendu de l'interface et le thread de déclenchement des événements du navigateur. se terminer après l'exécution, comme les threads de requête HTTP. Ces threads asynchrones généreront différents événements asynchrones, le diagramme suivant illustre comment un moteur JavaScript à thread unique interagit et communique avec d'autres threads. Bien que les détails d'implémentation de chaque noyau de navigateur soient différents, l'appel. les principes sont similaires.
Comme le montre l'image, le moteur JavaScript du navigateur est piloté par les événements. Les événements ici peuvent être considérés comme diverses tâches qui lui sont assignées. par le navigateur. Ces tâches peuvent provenir de JavaScript. Le bloc de code actuellement exécuté par le moteur, comme l'appel de setTimeout pour ajouter une tâche, peut également provenir d'autres threads du noyau du navigateur, tels que les événements de clic de souris sur les éléments d'interface, planifiés <.> déclenche notifications d'heure d'arrivée, notifications de changement de statut de demande asynchrone, etc. Du point de vue du code, les entités de tâche sont diverses fonctions de rappel. Le moteur JavaScript attend l'arrivée des tâches dans la file d'attente des tâches. relation monothread, ces tâches doivent être mises en file d'attente et traitées par le moteur l'une après l'autre
La figure ci-dessus t1-t2..tn représente différents moments dans le temps. Le petit carré correspondant en dessous de tn représente la tâche à. à ce moment-là. Supposons qu'il soit temps t1 et que le moteur s'exécute dans le code du bloc de tâches correspondant à t1. À ce moment-là, décrivons l'état des autres threads dans le noyau du navigateur. temps t1 :
Fil de rendu GUI : Ce fil est responsable du rendu de l'interface du navigateurPendant que le moteur JavaScript exécute le script, le thread de rendu du navigateur est dans un état suspendu, ce qui signifie qu'il est "gelé".Par conséquent, si vous effectuez des opérations de mise à jour sur l'interface dans un script, comme l'ajout de nœuds, la suppression de nœuds ou la modification de l'apparence des nœuds, les mises à jour ne seront pas reflétées immédiatement. Ces opérations seront enregistrées dans une file d'attente jusqu'à ce que le moteur JavaScript soit inactif. Ce n'est qu'alors qu'il sera possible de le faire. restituez-le.
Fil de déclenchement d'événement GUI :
L'exécution du script JavaScript n'affecte pas le déclenchement des événements d'élément HTML Pendant la période t1, l'utilisateur clique d'abord sur un bouton de souris. Le clic est capturé par le thread déclenchant l'événement du navigateur et forme un événement de clic de souris. Comme le montre la figure, pour le thread du moteur JavaScript, cet événement est transmis de manière asynchrone à la fin de la file d'attente des tâches par d'autres threads. Puisque le moteur traite la tâche à t1, cet événement de clic de souris attend d'être traité.
Fil de déclenchement de synchronisation :
Notez que le compteur de synchronisation du modèle de navigateur ici n'est pas compté par le moteur JavaScript, car le moteur JavaScript est monothread. S'il est dans un état de thread bloqué, il ne peut pas compter le temps. Il doit s'appuyer sur l'extérieur pour chronométrer et déclencher le timing, donc la file d'attente L'événement de timing est également un événement asynchrone
Comme le montre la figure, dans cette période t1. , après le déclenchement de l'événement de clic de souris, le timing setTimeout précédemment défini est également arrivé. À ce moment, pour le moteur JavaScript, le thread déclencheur génère un événement chronométré asynchrone et le place dans la file d'attente des tâches. le rappel de l'événement de clic et attend le traitement.
De même, toujours dans la période t1, une certaine minuterie setInterval est également appelée ensuite, en raison de la synchronisation par intervalle, elle a été déclenchée deux fois de suite au cours de la période t1, et celles-ci. deux événements ont été mis en file d'attente jusqu'à la fin de la file d'attente pour être traités.
On peut voir que si la période de temps t1 est très longue, beaucoup plus grande que l'intervalle de temps setInterval, alors le thread de déclenchement de synchronisation générera en continu des événements asynchrones. événements de timing et les placer à la fin de la file d'attente des tâches, qu'ils aient ou non été traités. Cependant, une fois que t1 et les tâches précédant le premier événement de timing ont été traitées, les tâches de ces arrangements seront exécutées en séquence. sans interruption. En effet, pour le moteur JavaScript, chaque tâche de la file d'attente de traitement est traitée de la même manière, mais l'ordre de traitement est différent
Après t1, c'est-à-dire celle actuellement traitée. La tâche a été renvoyée. Le moteur JavaScript vérifiera la file d'attente des tâches et constatera que la file d'attente actuelle n'est pas vide, il supprimera donc la tâche correspondante sous t2 et l'exécutera, et ainsi de suite à d'autres moments.
Si la file d'attente n'est pas vide, le moteur retirera une tâche de la tête de la file d'attente jusqu'à ce que la tâche soit traitée, c'est-à-dire qu'après son retour, le moteur exécutera la tâche suivante tâche. Les autres tâches de la file d'attente ne peuvent pas être exécutées avant le retour de la tâche.
Je pense que vous avez maintenant une idée claire de si JavaScript peut être multithread et que vous comprenez également. le mécanisme de fonctionnement de la minuterie JavaScript. Analysons quelques cas :
Cas 1 : setTimeout et setInterval
[javascript] afficher une copie simple ?
setTimeout(function(){
/* Bloc de code... */
setTimeout(arguments.callee, 10);
}, 🎜>
De nombreux camarades de classe et amis sont confus Puisque JavaScript est censé s'exécuter dans un seul thread, XMLHttpRequest est-il vraiment asynchrone après la connexion ?
En fait, la requête est bien asynchrone, mais cette requête est nouvellement ouverte par le navigateur. Une requête de thread (voir la figure ci-dessus), lorsque le statut demandé change, si un rappel a été défini précédemment, le thread asynchrone générera un statut. change et placez-le dans la file d'attente de traitement du moteur JavaScript pour attendre le traitement. Lorsque la tâche est traitée, le moteur JavaScript sera toujours une fonction de rappel exécutée à un seul thread. Plus précisément, il s'agit d'une fonction définie par un seul thread exécutant onreadystatechange. .L'utilisation de JS monothread et de navigateurs multithreads
Quelques problèmes mineurs concernant la conversion de type en js
Conversion de type d'affichage en JS
Comment implémenter le défilement horizontal et la navigation flottante en js
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!