Table des matières
Tout d'abord, expliquons ce qu'est la boucle d'événements :
Alors, voici la question. S’il y a de nombreuses tâches dans la file d’attente des tâches, laquelle doit être exécutée en premier ?
Remarque :
Maison interface Web js tutoriel Explication détaillée d'exemples de boucles d'événements js

Explication détaillée d'exemples de boucles d'événements js

Jun 26, 2017 am 09:17 AM
javascript 事件 循环

J'ai déjà lu quelques blogs sur les boucles d'événements, mais après ne pas les avoir lus pendant un moment, j'ai réalisé que je les avais tous oubliés, alors j'ai décidé d'écrire un blog pour les résumer !

Tout d'abord, expliquons ce qu'est la boucle d'événements :

Pour autant que nous le sachions, le js du navigateur est monothread, c'est-à-dire disons, au plus un seul segment de code s'exécute en même temps, mais le navigateur peut très bien gérer les requêtes asynchrones, alors pourquoi ? Regardons d'abord une image
Explication détaillée dexemples de boucles dévénements js
À partir de l'image ci-dessus, nous pouvons voir que le thread principal js a une pile d'exécution et que tout le code js s'exécutera dans la pile d'exécution. Lors de l'exécution du code, si vous rencontrez du code asynchrone (tel que setTimeout, ajax, promise.then et les clics de l'utilisateur, etc.), alors le navigateur mettra ces codes dans un thread (ici nous l'appelons un derrière-le -scenes thread) L'attente ne bloque pas l'exécution du thread principal. Le thread principal continue d'exécuter le code restant dans la pile lorsque le code du thread d'arrière-plan est prêt (par exemple, le délai setTimeout est écoulé et la requête ajax. reçoit une réponse), le thread le traitera. La fonction de rappel est placée dans la file d'attente des tâches en attente d'exécution. Lorsque le thread principal aura fini d'exécuter tout le code de la pile, il vérifiera s'il y a une tâche à exécuter dans la File d'attente des tâches S'il y a une tâche à exécuter, alors la tâche sera mise. dans la pile d'exécution pour l'exécution. Si la file d'attente des tâches actuelle est vide, elle continuera d'attendre en boucle que la tâche arrive. C’est ce qu’on appelle une boucle d’événements.

Alors, voici la question. S’il y a de nombreuses tâches dans la file d’attente des tâches, laquelle doit être exécutée en premier ?

En fait (comme le montre l'image ci-dessus), js a deux files d'attente de tâches, l'une s'appelle Macrotask Queue (Task Queue) et l'autre s'appelle Microtask Queue

  • Le premier est principalement utilisé pour effectuer des travaux à relativement grande échelle, les plus courants incluent setTimeout, setInterval, les opérations d'interaction utilisateur, le rendu de l'interface utilisateur, etc.

  • Le second est principalement utilisé pour effectuer des travaux à relativement petite échelle, ce qui est courant. Il existe Promise, process.nextTick (nodejs)

Alors, quelles sont les différences spécifiques entre les deux ? , si deux tâches apparaissent en même temps, laquelle faut-il choisir ?
En fait, ce que fait la boucle d'événements est la suivante :

  1. Vérifier si la file d'attente des macrotâches est vide . Sinon, passez à l'étape suivante. Si elle est vide, passez à 3

  2. Prendre la tâche en tête de file d'attente (avec le temps d'attente le plus long) depuis la liste. File d'attente Macrotask et exécutez-la dans la pile d'exécution (une seule). Après l'exécution, passez à l'étape suivante

  3. Vérifiez si la file d'attente Microtask est vide, sinon passez à l'étape suivante. , sinon, passez à 1 (démarrez une nouvelle boucle d'événements)

  4. Obtenir de la file d'attente Microtask La tâche en tête de file d'attente (avec le temps le plus long dans la file d'attente) va dans la file d'attente des événements pour l'exécution. Après l'exécution, passe à 3

Parmi eux, la tâche de microtâche ajoutée lors de l'exécution du code sera dans la période actuelle de la boucle d'événement. , et la tâche de macrotâche nouvellement ajoutée ne peut attendre que la prochaine boucle d'événement pour s'exécuter (une boucle d'événement n'exécute qu'une seule macrotâche)
Tout d'abord, regardons un morceau de code

console.log(1)
setTimeout(function() {
  //settimeout1
  console.log(2)
}, 0);
const intervalId = setInterval(function() {
  //setinterval1
  console.log(3)
}, 0)
setTimeout(function() {
  //settimeout2
  console.log(10)
  new Promise(function(resolve) {
    //promise1
    console.log(11)
    resolve()
  })
  .then(function() {
    console.log(12)
  })
  .then(function() {
    console.log(13)
    clearInterval(intervalId)
  })
}, 0);

//promise2
Promise.resolve()
  .then(function() {
    console.log(7)
  })
  .then(function() {
    console.log(8)
  })
console.log(9)
Copier après la connexion

Que voulez-vous pensez-vous que le résultat devrait être ?
Les résultats que je génère dans l'environnement de nœud et la console Chrome sont les suivants :

1
9
7
8
2
3
10
11
12
13
Copier après la connexion

Dans l'exemple ci-dessus
la première boucle d'événement :

  1. console.log(1) est exécuté, sortie 1

  2. settimeout1 est exécuté et ajouté à la file d'attente des macrotâches

  3. setinterval1 est exécuté et ajouté à la file d'attente des macrotâches

  4. settimeout2 est exécuté et ajouté à la file d'attente des macrotâches

  5. promise2 est exécuté et ses deux La fonction then est ajoutée à la file d'attente des microtâches

  6. console.log(9) est exécutée et la sortie est 9

  7. Selon la définition de la boucle d'événements, new sera exécuté ensuite. Les tâches de microtâches ajoutées sont exécutées dans l'ordre d'entrée dans la file d'attente. Console.log(7) et console.log(8) sont affichés. sont affichés. La file d'attente des microtâches est vide. Revenez à la première étape et entrez dans la boucle d'événements suivante. À ce stade, la file d'attente des macrotâches est : settimeout1, setinterval1, settimeout2

La deuxième boucle d'événements :

    de la file d'attente des macrotâches Obtenez la tâche en tête de l'équipe (settimeout1) et exécutez-la Sortie 2
  1. La file d'attente des microtâches est. vide. Revenez à la première étape et entrez dans la boucle d'événements suivante. À ce stade, la file d'attente des macrotâches est : setinterval1, settimeout2


La troisième boucle d'événements :

.

    Prenez la tâche à la tête de l'équipe (setinterval1) de la file d'attente des macrotâches et exécutez-la, sortie 3, puis ajoutez le setinterval1 nouvellement généré à la file d'attente des macrotâches
  1. Le La file d'attente des microtâches est vide, revenez à la première étape et entrez dans la boucle d'événements suivante. À ce moment, la file d'attente des macrotâches est : settimeout2, setinterval1


La quatrième boucle d'événements :

    Prenez la tâche à la tête de l'équipe (settimeout2) de la file d'attente des macrotâches et exécutez-la, sortie 10, et exécutez la fonction dans la nouvelle promesse (la fonction dans la nouvelle promesse est une opération synchrone, pas une opération asynchrone), sortie 11, et ajoute ses deux fonctions then à la file d'attente des microtâches
  1. Depuis la file d'attente des microtâches, prenez la tâche en tête de file d'attente et exécutez-la jusqu'à ce qu'elle soit vide. Par conséquent, les deux tâches de microtâches nouvellement ajoutées sont exécutées en séquence, sorties 12 et 13, et setinterval1 est effacé
    À ce moment, la file d'attente des microtâches et la file d'attente des macrotâches sont vides, et le navigateur vérifiera toujours si la file d'attente est vide et attends le nouveau. La tâche est ajoutée à la file d'attente.

Ici, vous vous demandez peut-être, dans la première boucle, pourquoi la macrotâche n'est-elle pas exécutée en premier ? Car selon le processus, ne devrions-nous pas d'abord vérifier si la file d'attente des macrotâches est vide, puis vérifier la file d'attente des microtâches ?
Raison : Parce que la tâche exécutée dans le thread principal js au début est la tâche de macrotâche, et selon le processus de la boucle d'événement, une seule tâche de macrotâche sera exécutée dans une boucle d'événement. Par conséquent, après l'exécution du code. du thread principal, il ira de Prenez la première tâche de la file d'attente des microtâches et exécutez-la.

Remarque :

Lors de l'exécution d'une tâche de microtâche, elle n'entrera dans la boucle d'événements suivante que lorsque la file d'attente des microtâches est vide. Par conséquent, si elle génère continuellement de nouvelles. Les tâches de microtâches entraîneront l'exécution de tâches de microtâches par le thread principal, et il n'y a aucun moyen d'exécuter des tâches de macrotâches. De cette façon, nous ne pourrons pas effectuer de rendu d'interface utilisateur/opérations d'E/S/requêtes ajax. Par conséquent, nous devrions éviter cette situation. . se produire. Dans process.nexttick dans nodejs, vous pouvez définir le nombre maximum d'appels pour éviter de bloquer le thread principal.

Avec cela, nous introduisons un nouveau problème, le problème de la minuterie. La minuterie est-elle réelle et fiable ? Par exemple, si j'exécute une commande : setTimeout(task, 100), sera-t-elle exécutée exactement après 100 millisecondes ? En fait, sur la base de la discussion ci-dessus, nous pouvons savoir que cela est impossible.
Je pense que tout le monde devrait connaître la raison, car après avoir exécuté setTimeout(task,100), vous vous assurez simplement que la tâche entrera dans la file d'attente des macrotâches après 100 millisecondes, mais cela ne signifie pas qu'elle peut s'exécuter immédiatement, peut-être Le thread principal effectue actuellement une opération fastidieuse, ou il peut y avoir de nombreuses tâches dans la file d'attente des microtâches, c'est peut-être la raison pour laquelle tout le monde a critiqué setTimeout

Ce qui précède n'est que mon point de vue personnel. de la boucle événementielle. Quelques avis et références d'autres excellents articles

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 de ce site Web
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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Tutoriel JavaScript simple : Comment obtenir le code d'état HTTP Tutoriel JavaScript simple : Comment obtenir le code d'état HTTP Jan 05, 2024 pm 06:08 PM

Tutoriel JavaScript : Comment obtenir le code d'état HTTP, des exemples de code spécifiques sont requis Préface : Dans le développement Web, l'interaction des données avec le serveur est souvent impliquée. Lors de la communication avec le serveur, nous devons souvent obtenir le code d'état HTTP renvoyé pour déterminer si l'opération a réussi et effectuer le traitement correspondant en fonction de différents codes d'état. Cet article vous apprendra comment utiliser JavaScript pour obtenir des codes d'état HTTP et fournira quelques exemples de codes pratiques. Utilisation de XMLHttpRequest

Comment implémenter la liaison d'événement de changement d'éléments sélectionnés dans jQuery Comment implémenter la liaison d'événement de changement d'éléments sélectionnés dans jQuery Feb 23, 2024 pm 01:12 PM

jQuery est une bibliothèque JavaScript populaire qui peut être utilisée pour simplifier la manipulation du DOM, la gestion des événements, les effets d'animation, etc. Dans le développement Web, nous rencontrons souvent des situations dans lesquelles nous devons modifier la liaison d'événements sur des éléments sélectionnés. Cet article explique comment utiliser jQuery pour lier des événements de modification d'éléments sélectionnés et fournit des exemples de code spécifiques. Tout d'abord, nous devons créer un menu déroulant avec des options utilisant des étiquettes :

L'expression lambda sort de la boucle L'expression lambda sort de la boucle Feb 20, 2024 am 08:47 AM

L'expression Lambda sort de la boucle, des exemples de code spécifiques sont nécessaires en programmation, la structure de boucle est une syntaxe importante qui est souvent utilisée. Cependant, dans certaines circonstances, nous pouvons vouloir sortir de la boucle entière lorsqu'une certaine condition est remplie dans le corps de la boucle, plutôt que de simplement terminer l'itération en cours de la boucle. À l'heure actuelle, les caractéristiques des expressions lambda peuvent nous aider à atteindre l'objectif de sortir de la boucle. L'expression Lambda est un moyen de déclarer une fonction anonyme, qui peut définir une logique de fonction simple en interne. C'est différent d'une déclaration de fonction ordinaire,

Comment obtenir facilement le code d'état HTTP en JavaScript Comment obtenir facilement le code d'état HTTP en JavaScript Jan 05, 2024 pm 01:37 PM

Introduction à la méthode d'obtention du code d'état HTTP en JavaScript : Dans le développement front-end, nous devons souvent gérer l'interaction avec l'interface back-end, et le code d'état HTTP en est une partie très importante. Comprendre et obtenir les codes d'état HTTP nous aide à mieux gérer les données renvoyées par l'interface. Cet article explique comment utiliser JavaScript pour obtenir des codes d'état HTTP et fournit des exemples de code spécifiques. 1. Qu'est-ce que le code d'état HTTP ? Le code d'état HTTP signifie que lorsque le navigateur lance une requête au serveur, le service

PHP renvoie toutes les valeurs du tableau pour former un tableau PHP renvoie toutes les valeurs du tableau pour former un tableau Mar 21, 2024 am 09:06 AM

Cet article expliquera en détail comment PHP renvoie toutes les valeurs d'un tableau pour former un tableau. L'éditeur pense que c'est assez pratique, je le partage donc avec vous comme référence. J'espère que vous pourrez gagner quelque chose après avoir lu cet article. . Utilisation de la fonction array_values() La fonction array_values() renvoie un tableau de toutes les valeurs d'un tableau. Il ne conserve pas les clés du tableau d'origine. $array=["foo"=>"bar","baz"=>"qux"];$values=array_values($array);//$values ​​​​sera ["bar","qux"]Utilisation une boucle peut utiliser une boucle pour obtenir manuellement toutes les valeurs du tableau et les ajouter à un nouveau

Comment créer des applications basées sur des événements en utilisant PHP Comment créer des applications basées sur des événements en utilisant PHP May 04, 2024 pm 02:24 PM

Les méthodes de création d'applications basées sur des événements en PHP incluent l'utilisation d'EventSourceAPI pour créer une source d'événements et l'utilisation de l'objet EventSource pour écouter les événements côté client. Envoyez des événements à l'aide de Server Sent Events (SSE) et écoutez les événements côté client à l'aide d'un objet XMLHttpRequest. Un exemple pratique consiste à utiliser EventSource pour mettre à jour les inventaires en temps réel sur un site Web de commerce électronique. Ceci est réalisé côté serveur en modifiant l'inventaire de manière aléatoire et en envoyant des mises à jour, et le client écoute les mises à jour d'inventaire via EventSource et les affiche dans. temps réel.

Java Iterator vs Iterable : une étape vers l'écriture de code élégant Java Iterator vs Iterable : une étape vers l'écriture de code élégant Feb 19, 2024 pm 02:54 PM

Interface Iterator L'interface Iterator est une interface utilisée pour parcourir les collections. Il fournit plusieurs méthodes, notamment hasNext(), next() et remove(). La méthode hasNext() renvoie une valeur booléenne indiquant s'il existe un élément suivant dans la collection. La méthode next() renvoie l'élément suivant de la collection et le supprime de la collection. La méthode Remove() supprime l'élément actuel de la collection. L'exemple de code suivant montre comment utiliser l'interface Iterator pour parcourir une collection : Listnames=Arrays.asList("John","Mary","Bob");Iterator

Quelles sont les alternatives aux appels récursifs dans les fonctions Java ? Quelles sont les alternatives aux appels récursifs dans les fonctions Java ? May 05, 2024 am 10:42 AM

Remplacement des appels récursifs dans les fonctions Java par itération En Java, la récursivité est un outil puissant utilisé pour résoudre divers problèmes. Cependant, dans certains cas, l’utilisation de l’itération peut s’avérer une meilleure option car elle est plus efficace et moins sujette aux débordements de pile. Voici les avantages de l'itération : Plus efficace puisqu'elle ne nécessite pas la création d'un nouveau stack frame à chaque appel récursif. Les débordements de pile sont moins susceptibles de se produire car l'utilisation de l'espace de pile est limitée. Méthodes itératives comme alternative aux appels récursifs : Il existe plusieurs méthodes en Java pour convertir des fonctions récursives en fonctions itératives. 1. Utiliser la pile L'utilisation de la pile est le moyen le plus simple de convertir une fonction récursive en fonction itérative. La pile est une structure de données dernier entré, premier sorti (LIFO), similaire à une pile d'appels de fonction. publicintfa

See all articles