Maison  >  Article  >  interface Web  >  Mécanisme de boucle d'événements du navigateur JS

Mécanisme de boucle d'événements du navigateur JS

不言
不言original
2018-07-07 17:11:441584parcourir

Cet article présente principalement le mécanisme de boucle d'événements du navigateur JS, qui a une certaine valeur de référence. Maintenant, je le partage avec tout le monde. Les amis dans le besoin peuvent s'y référer

Tout d'abord, comprenons quelques contenus conceptuels.

Processus, thread

  • Un processus est une ressource indépendante allouée par le système et l'unité de base d'allocation des ressources CPU. Un processus est composé d'un ou plusieurs threads.

  • Le thread est le flux d'exécution d'un processus et l'unité de base de la planification et de la répartition du processeur. Plusieurs threads dans le même processus partagent les ressources du processus.

Noyau du navigateur

  • Le navigateur est multi-processus, et chaque étiquette d'onglet du navigateur représente un processus indépendant (pas nécessairement, car plusieurs les étiquettes d'onglets vides seront fusionnées en un seul processus), le noyau du navigateur (processus de rendu du navigateur) est l'un des multi-processus du navigateur.

  • Le noyau du navigateur fait fonctionner plusieurs threads.

    • Lors d'une requête http, un fil de discussion sera ouvert.

    • Une fois la requête terminée et le résultat obtenu, ajoutez la fonction de rappel demandée à la file d'attente des tâches et attendez le traitement par le moteur JS.

    • Le compteur de timing du navigateur n'est pas compté par le moteur JS, et le blocage entraînera un timing inexact.

    • Activez le thread de déclenchement du minuteur pour chronométrer et déclencher le timing. Une fois le timing terminé, il sera ajouté à la file d'attente des tâches et attendra son traitement par le moteur JS.

    • Lorsqu'un événement remplit les conditions de déclenchement et est déclenché, le thread ajoutera la fonction de rappel d'événement correspondante à la fin de la file d'attente des tâches et attendra son traitement par le moteur JS.

    • Travail monothread, responsable de l'analyse et de l'exécution des scripts JavaScript.

    • et le fil de rendu de l'interface graphique s'excluent mutuellement. Si JS met trop de temps à s'exécuter, la page sera bloquée.

    • est responsable du rendu de la page, de l'analyse du HTML, du CSS pour former une arborescence DOM, etc. Ce fil de discussion sera appelé lorsque la page est redessinée ou que la redistribution est provoquée par une opération.

    • et le thread du moteur JS s'excluent mutuellement. Lorsque le thread du moteur JS fonctionne, le thread de rendu de l'interface graphique sera suspendu et la mise à jour de l'interface graphique sera placée dans la file d'attente des tâches JS, en attente. Le thread du moteur JS continue son exécution lorsqu'il est inactif.

    • Fil de rendu GUI :

    • Fil de discussion du moteur JS :

    • Fil de déclenchement d'événement :

    • Fil de déclenchement du minuteur :

    • Fil de demande http :

Mécanisme de boucle dévénements du navigateur JS

Le moteur JavaScript est monothread

Le moteur JavaScript est monothread, ce qui signifie qu'une seule tâche peut être exécutée à la fois et que les autres tâches doivent être mises en file d'attente pour être exécutées. Seule la tâche en cours est exécutée. Une fois terminée, la tâche suivante sera exécutée.

L'API Web-Worker est proposée en HTML5, principalement pour résoudre le problème du blocage des pages, mais elle ne change pas la nature monothread de JavaScript. Découvrez les Web-Workers.

Mécanisme de boucle d'événements JavaScript

Le mécanisme de boucle d'événements JavaScript est divisé en mécanismes de boucle d'événements de navigateur et de nœud. Les technologies d'implémentation des deux sont différentes. Event Loop est implémenté par la bibliothèque libuv. L'objectif principal ici est la partie navigateur.

Javascript a un thread principal et une pile d'appels (pile d'exécution). Toutes les tâches seront placées sur la pile d'appels pour attendre que le thread principal s'exécute.

  • Pile d'appels JS

    La pile d'appels JS est une structure de données dernier entré, premier sorti. Lorsqu'une fonction est appelée, elle est ajoutée en haut de la pile. Une fois l'exécution terminée, la fonction est supprimée du haut de la pile jusqu'à ce que la pile soit effacée.

  • Tâches synchrones, tâches asynchrones

    Les tâches du thread unique JavaScript sont divisées en tâches synchrones et tâches asynchrones. Les tâches synchrones seront mises en file d'attente dans l'ordre dans la pile d'appels en attendant que le thread principal s'exécute, tandis que les tâches asynchrones ajouteront la fonction de rappel enregistrée à la file d'attente des tâches (file d'attente des messages) une fois que les résultats asynchrones sont disponibles, en attendant que le thread principal soit inactif, c'est-à-dire dans la pile. Lorsqu'il est effacé, il est lu dans la pile et attend son exécution par le thread principal. La file d'attente des tâches est une structure de données premier entré, premier sorti.

  • Boucle d'événement

    Les tâches de synchronisation dans la pile d'appels ont été exécutées et la pile a été effacée, ce qui signifie que le thread principal est inactif et ira au file d'attente des tâches à ce moment-là. Une tâche est lue en séquence et placée sur la pile pour exécution. Chaque fois que la pile est effacée, elle lira s'il y a des tâches dans la file d'attente des tâches, et s'il y a des tâches, elle sera lue et exécutée. L'opération de lecture et d'exécution formera une boucle d'événements.

Mécanisme de boucle dévénements du navigateur JS

Mécanisme de boucle dévénements du navigateur JS

  • Minuterie

    La minuterie démarrera une minuterie. timer déclenche le thread pour déclencher le timing.Après avoir attendu le temps spécifié, le timer placera l'événement dans la file d'attente des tâches et attendra d'être lu et exécuté par le thread principal.

    Le délai en millisecondes spécifié par le minuteur n'est en fait pas précis, car le minuteur ne place l'événement dans la file d'attente des tâches que lorsque l'heure spécifiée est atteinte et doit attendre que la tâche synchronisée et l'événement dans la file d'attente des tâches existante soient terminés. toutes les exécutions sont terminées, les événements du minuteur seront lus et exécutés sur le thread principal. Il peut y avoir des tâches qui prennent beaucoup de temps au milieu, il est donc impossible de garantir l'exécution à l'heure spécifiée.

  • Macro-tâche (macro-tâche), micro-tâche (micro-tâche)

    En plus des tâches synchrones généralisées et des tâches asynchrones, les tâches dans un seul JavaScript le fil peut être détaillé Divisé en macro-tâches et micro-tâches.

    la macro-tâche comprend : script (code global), setTimeout, setInterval, setImmediate, I/O, rendu UI.

    La micro-tâche comprend : process.nextTick, Promises, Object.observe, MutationObserver.

        console.log(1);
        setTimeout(function() {
            console.log(2);
        })
        var promise = new Promise(function(resolve, reject) {
            console.log(3);
            resolve();
        })
        promise.then(function() {
            console.log(4);
        })
        console.log(5);

    Dans l'exemple, setTimeout et Promise sont appelés sources de tâches, et les fonctions de rappel enregistrées à partir de différentes sources de tâches seront placées dans différentes files d'attente de tâches.

    Après avoir les notions de macro tâches et de micro tâches, quel est l'ordre d'exécution de JS ? Les macro-tâches ou les micro-tâches doivent-elles passer en premier ?

    Dans la première boucle d'événement, le moteur JavaScript exécutera l'intégralité du code du script en tant que macrotâche. Une fois l'exécution terminée, il détectera s'il y a une microtâche dans cette boucle. Si elle existe, elle démarrera. à partir de la microtâche dans l'ordre.Une fois que toutes les microtâches sont lues et exécutées dans la file d'attente des tâches, les tâches de la file d'attente des tâches de la macrotâche sont lues et exécutées, puis toutes les microtâches sont exécutées, et ainsi de suite. La séquence d'exécution de JS est constituée des macro-tâches-micro-tâches dans chaque boucle d'événement.

    • Dans l'exemple ci-dessus, dans la première boucle d'événements, l'intégralité du code entre dans le thread principal pour être exécuté en tant que tâche macro.

    • Lorsqu'il rencontre setTimeout, il attendra que le temps spécifié soit écoulé et placera la fonction de rappel dans la file d'attente des tâches de la macro-tâche.

    • Lorsque vous rencontrez une promesse, placez la fonction then dans la file d'attente des tâches de la microtâche.

    • Une fois toute la boucle d'événements terminée, il détectera s'il y a une tâche dans la file d'attente des tâches de la microtâche et l'exécutera si elle existe.

    • Le résultat de la première boucle est imprimé comme : 1,3,5,4.

    • Ensuite, allez dans la file d'attente des tâches de la tâche macro et retirez une tâche macro dans l'ordre et placez-la sur la pile pour que le thread principal s'exécute. Ensuite, la tâche macro dans cette boucle. est la fonction de rappel enregistrée par setTimeout , après avoir exécuté cette fonction de rappel, il s'avère qu'il n'y a pas de microtâches dans cette boucle et nous sommes prêts pour la prochaine boucle d'événements.

    • S'il est détecté qu'il n'y a aucune tâche à exécuter dans la file d'attente des tâches macro, alors la boucle d'événements se terminera.

    • Le résultat final est 1,3,5,4,2.

    Ce qui précède représente l'intégralité du contenu de cet article. J'espère qu'il sera utile à l'étude de chacun. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois !

    Recommandations associées :

    Minuterie JS et fonctionnalités asynchrones à thread unique

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn