Maison  >  Article  >  interface Web  >  Comment fonctionne la minuterie javascript

Comment fonctionne la minuterie javascript

高洛峰
高洛峰original
2017-02-04 17:19:141373parcourir

Quand on parle de timers en javascript, on pensera certainement aux deux fonctions setTimeout() et setInterval(). Cet article analysera les principes de fonctionnement et les différences entre les deux du point de vue de la boucle d'événements.

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 identifiant peut être utilisé comme paramètre de clearTimeout pour annuler le timer :

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

IE0 prend également en charge la transmission 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.

Puisque 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énements de JavaScript, le deuxième paramètre ne représente pas l'exécution de la fonction de rappel immédiatement après le délai de quelques millisecondes, mais tente de La fonction de rappel est ajoutée à la file d'attente des événements. En fait, il y a une différence dans le traitement entre 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 à la file d'attente des événements.

setInterval : Après avoir retardé 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, n'ajoutez pas de fonction de rappel au). file d'attente des événements.

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

Comprenons à travers un exemple

Le code suivant espérait à l'origine pouvoir appeler la fonction de rappel à 100 ms et 200 ms (c'est-à-dire en attendant juste 100 ms) :

var timerStart1 = now();
setTimeout(function () {
console.log('Le premier temps d'attente d'exécution du rappel setTimeout :', now() - timerStart1);

var timerStart2 = now( );
setTimeout(function () {
console.log('Deuxième temps d'attente d'exécution du rappel setTimeout :', now() - timerStart2);
}, 100);
}, 100);
// Sortie :
// Temps d'attente pour la première exécution du rappel setTimeout : 106
// Temps d'attente pour la deuxième exécution du rappel setTimeout : 107

J'aime this Le résultat ressemble à ce à quoi nous nous attendions, mais une fois que nous ajoutons des tâches fastidieuses au code, le résultat n'est pas celui auquel nous nous attendions :

var timerStart1 = now();
setTimeout(function () {
console.log('Premier temps d'attente d'exécution du rappel setTimeout :', now() - timerStart1);

var timerStart2 = now();
setTimeout(function () {
console.log('Délai d'attente de l'exécution du deuxième rappel setTimeout :', now() - timerStart2);
}, 100);

heavyTask() ; // Tâche chronophage
}, 100);

var loopStart = now();
heavyTask(); // Tâche chronophage
console.log('heavyTask prend du temps :', now() - loopStart);

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

function now () {
return new Date();
}
// Sortie :
// Consommation de temps heavyTask : 1015
// Temps d'attente de l'exécution du premier rappel setTimeout : 1018
// Temps d'attente d'exécution du deuxième rappel setTimeout : 1000

Les événements d'attente des deux setTimeout ne sont plus de 100 ms en raison de l'existence de tâches chronophages. Décrivons ce qui s'est passé :

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

Commencez à exécuter 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. Cependant, la tâche fastidieuse précédente n'a pas encore été exécutée. , donc il ne peut qu'attendre dans la file d'attente et il ne commencera pas l'exécution tant que la tâche fastidieuse n'est pas terminée, donc ce que nous voyons dans le résultat est : Le temps d'attente de l'exécution du premier rappel setTimeout : 1018.

Dès que le premier rappel setTimeout est exécuté, le deuxième setTimeout est démarré. Ce timer 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.

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

javascript 定时器工作原理

Regardons un exemple de setInterval :

var intervalStart = now();
setInterval(function () {
console.log(' interval Le temps écoulé depuis la définition du minuteur : ', now() - loopStart);
}, 100);

var loopStart = now();
heavyTask();
console .log ('heavyTask prend du temps :', now() - loopStart);

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

fonction maintenant () {
return new Date();
}
// Sortie :
// consommation de temps de tâche lourde : 1013
//Intervalle du timer défini : 1016
//Intervalle du timer défini : 1123
//Intervalle du timer défini : 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.

Il peut être résumé par le schéma suivant :

javascript 定时器工作原理

Résumé

Ce qui précède est une brève analyse du principe d'exécution du minuteur JavaScript. J'espère que cela pourra nous aider à comprendre javascript plus profondément. S'il y a des descriptions inappropriées dans l'article, veuillez les signaler dans les commentaires.

Pour plus d'articles liés au principe de fonctionnement du minuteur javascript, veuillez faire attention au site Web PHP 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