Maison  >  Article  >  interface Web  >  Comportement de blocage de l'interface utilisateur : microtâches et macrotâches

Comportement de blocage de l'interface utilisateur : microtâches et macrotâches

WBOY
WBOYoriginal
2024-08-31 06:32:02712parcourir

UI Blocking behaviour: microtasks vs macrotasks

Pouvez-vous trouver la différence entre les deux extraits de code ci-dessous :

function handleClick1() {
     setTimeout(handleClick1, 0);
}

function handleClick2() {
     Promise.resolve().then(handleClick2);
}

Si vous n'êtes pas en mesure d'identifier les implications du choix de l'un plutôt que de l'autre, alors cet article de blog vous apprendra quelque chose de nouveau.

Arrière-plan

setTimeout permet de planifier un rappel après un certain laps de temps. Promise.resolve().then fera la même chose efficacement, mais en interne, les deux sont différents. Ce dernier renvoie une promesse déjà résolue. L'appel de then(callback) sur cette promesse planifiera l'exécution du rappel.

Ainsi, les deux fonctions ci-dessus s'appellent de manière récursive avec un délai minimal. La différence est que le rappel de setTimeout est placé dans la file d'attente des macrotâches et qu'un rappel d'un promise.then() est placé dans la file d'attente des microtâches. La façon dont la boucle d'événements traite les éléments de ces deux files d'attente est ce qui fait la différence entre les 2 extraits de code ci-dessus.

Traitement de la boucle d'événements de la microtâche par rapport à la macrotâche

Tout ce qu'une boucle d'événements fait, c'est que lorsqu'il y a des tâches à effectuer, elle les exécute, puis se met en veille et attend d'autres tâches.

Les macrotâches (ou simplement les tâches) incluent des fonctions responsables du travail telles que :

  1. Analyse
  2. Réagir au DOM,

entre autres...

Après l'exécution d'une tâche sélectionnée dans la file d'attente des tâches, la boucle d'événements effectue un point de contrôle de microtâche. L'algorithme pour lequel est quelque chose comme :

While microtask queue is not empty, pick the oldest task from microtask queue and execute it.

Cela signifie que si une microtâche met en file d'attente une autre microtâche, cette tâche sera exécutée avant la macrotâche suivante. Et comme le rendu de l'interface utilisateur est une macrotâche, elle ne sera jamais exécutée par la boucle d'événements.

Voici une démo pour ce qui précède : démo JS Bin. Une animation infinie est en cours. Si nous déclenchons handleClick1, nous ajoutons un traitement au thread principal, mais l'animation s'affiche toujours correctement. Mais si nous déclenchons handleClick2, l'animation s'arrête.

J'ai ajouté la variable totalCount, afin que nous puissions arrêter avant que la page ne plante. Mais ce qui est remarquable, c'est qu'une fois la boucle microTask démarrée, l'interface utilisateur ne répond plus pendant un certain temps. Parce que des tâches telles que le rendu, la réaction au DOM, etc. ne seront exécutées qu'une fois la file d'attente des microtâches vide.

Cela fait de handleClick1 de l'extrait de code ci-dessus un choix plus sûr. J'espère que le blog a aidé à expliquer une différence fondamentale entre les microtâches et les macrotâches.

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