Maison  >  Article  >  interface Web  >  Analyse des principes des timers en JavaScript

Analyse des principes des timers en JavaScript

黄舟
黄舟original
2017-11-18 13:53:481554parcourir

Dans notre travail, beaucoup de gens pensent aux deux fonctions setTimeout() et setInterval() lorsqu'ils parlent du timer en javascript, mais ils ne connaissent pas le timer en JavaScript. Quel est le principe, alors cet article analysera le principe de fonctionnement et la différence de la fonction timer du point de vue de la boucle d'événement (Event Loop) !

setTimeout()

MDN définit setTimeout comme :

Appelle une fonction ou exécute un fragment de code après le délai spécifié.

Syntaxe

La syntaxe de setTimeout est très simple. Le premier paramètre est la fonction de rappel, et le deuxième paramètre est le temps de retard. La fonction renvoie un identifiant unique de type numérique Cet ID peut être utilisé comme paramètre de clearTimeout pour annuler le timer :

var timeoutID = window.setTimeout(code, delay);

IE0+ prend également en charge le passage de paramètres de rappel :

var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);

setInterval()

MDN définit setInterval comme :

Appelez périodiquement une fonction ou exécutez un morceau de code.

Étant donné que l'utilisation de setInterval et setTimeout est la même, ils ne sont plus répertoriés ici.

Explication du deuxième paramètre (délai)

En raison du mécanisme de boucle d'événement de JavaScript, le deuxième paramètre ne signifie pas que le rappel sera exécuté immédiatement après le retarder les millisecondes, essayez plutôt d'ajouter la fonction de rappel à la file d'attente des événements. En fait, il y a une différence dans le traitement de setTimeout et setInterval à ce stade :

  • setTimeout : Après le délai de quelques millisecondes, quoi qu'il arrive, la fonction de rappel est directement ajoutée à l'événement file d'attente.

  • setInterval : Après le délai de quelques millisecondes, vérifiez d'abord s'il existe une fonction de rappel dans la file d'attente des événements qui n'a pas encore été exécutée (la fonction de rappel de setInterval, si elle existe). ne plus accéder à la file d'attente des événements. Une fonction de rappel a été ajoutée.

Ainsi, lorsqu'il y a des tâches chronophages dans notre code, le minuteur ne se comportera pas comme nous le pensons.

A travers un exemple pour comprendre le code suivant

, j'espérais au départ pouvoir appeler la fonction de rappel à 100 ms et 200 ms (c'est-à-dire attendre juste 100 ms ):

var timerStart1 = now();
setTimeout(function () {
 console.log('第一个setTimeout回调执行等待时间:', now() - timerStart1);
 var timerStart2 = now();
 setTimeout(function () {
  console.log('第二个setTimeout回调执行等待时间:', now() - timerStart2);
 }, 100);
}, 100);
// 输出:
// 第一个setTimeout回调执行等待时间: 106
// 第二个setTimeout回调执行等待时间: 107

Le résultat ressemble à ce à quoi nous nous attendions, mais une fois que l'on ajoute des tâches chronophages au code, le résultat n'est pas celui attendu :

var timerStart1 = now();
setTimeout(function () {
 console.log('第一个setTimeout回调执行等待时间:', now() - timerStart1);

 var timerStart2 = now();
 setTimeout(function () {
  console.log('第二个setTimeout回调执行等待时间:', now() - timerStart2);
 }, 100);

 heavyTask(); // 耗时任务
}, 100);

var loopStart = now();
heavyTask(); // 耗时任务
console.log('heavyTask耗费时间:', now() - loopStart);

function heavyTask() {
 var s = now();
 while(now() - s < 1000) {
 }
}

function now () {
 return new Date();
}
// 输出:
// heavyTask耗费时间: 1015
// 第一个setTimeout回调执行等待时间: 1018
// 第二个setTimeout回调执行等待时间: 1000

L'attente les événements des deux setTimeout ne sont plus de 100ms du fait de l'existence de tâches chronophages ! Décrivons ce qui s'est passé :

  1. Tout d'abord, la première tâche fastidieuse (heavyTask()) commence à s'exécuter et prend environ 1 000 ms pour se terminer.

  2. Démarrez l'exécution à partir de la tâche fastidieuse. Après 100 ms, la première fonction de rappel setTimeout devrait être exécutée, elle est donc ajoutée à la file d'attente des événements, mais à ce moment-là, la précédente. la tâche fastidieuse n'a pas encore été exécutée. Après l'exécution, elle ne peut qu'attendre dans la file d'attente jusqu'à ce que la tâche fastidieuse soit terminée, donc ce que nous voyons dans le résultat est : Le premier temps d'attente d'exécution du rappel setTimeout : 1018.

  3. Dès que le premier rappel setTimeout est exécuté, le deuxième setTimeout est démarré. Cette minuterie devrait également exécuter sa fonction de rappel après un délai de 100 ms. Cependant, il existe une autre tâche fastidieuse dans le premier setTimeout. Son tracé est le même que celui du premier minuteur, et il attend également 1 000 ms avant de commencer l'exécution.

peut être résumé par l'image suivante :

Regardons un exemple de setInterval :

var intervalStart = now();
setInterval(function () {
 console.log(&#39;interval距定义定时器的时间:&#39;, now() - loopStart);
}, 100);
var loopStart = now();
heavyTask();
console.log(&#39;heavyTask耗费时间:&#39;, now() - loopStart);
function heavyTask() {
 var s = now();
 while(now() - s < 1000) {
 }
}
function now () {
 return new Date();
}
// 输出:
// heavyTask耗费时间: 1013
// interval距定义定时器的时间: 1016
// interval距定义定时器的时间: 1123
// interval距定义定时器的时间: 1224

Dans le code ci-dessus, nous prévoyons d'imprimer un journal toutes les 100 ms. Par rapport à setTimeout, setInterval déterminera s'il y a des rappels non exécutés dans la file d'attente lors de la préparation de l'ajout de la fonction de rappel à la file d'attente des événements. Si tel est le cas, il n'ajoutera pas la fonction de rappel à la file d'attente. Sinon, plusieurs rappels seront exécutés en même temps.

peut être résumé par l'image suivante :

Résumé :

Partie 1 Après une brève analyse du principe d'exécution du timer JavaScript, je pense que mes amis ont une certaine compréhension du principe de fonctionnement du timer JavaScript. J'espère que cela pourra vous aider.

Recommandations associées :

Exemple de code de minuterie Javascript

Exploration approfondie des minuteries javascript

Exemple complet de minuterie javascript

Minuterie JavaScript et méthode de minuterie d'annulation optimisée

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