Veuillez lire le code suivant et devinez le résultat de l'exécution:
var start = new Date; setTimeOut (function () {console.log ('Time passe:' + (new Date - start) + 'msec');}, 200); while (new Date - start <1000) {} console.log (1); fonction Dosoming () {setTimeout (function () {console.log ('temps passe à nouveau:' + (new Date - start) + 'msec');}, 10);} dosoming (); while (nouvelle date - démarrer <2000) {} console.log (2);s'avérer:
Sortie après environ 1 seconde: 1,
Après environ 1 seconde, la sortie est: 2.
Puis la sortie immédiatement: le temps passé: 2002 millisecondes
Dernière sortie: le temps passé à nouveau: 2003 millisecondes
L'avez-vous deviné non?
Ici, toutes les fonctions qui retardent l'exécution par setTimeout sont poussées à la fin avant l'exécution;
Le principe est le suivant:
Dans l'environnement du navigateur existant, le moteur d'exécution JavaScript est unique. Les instructions et méthodes du thread principal bloqueront l'exécution des tâches de synchronisation. En dehors du moteur d'exécution JavaScript, il y a une file d'attente de tâches. Lorsque la méthode setTimeout () est appelée dans le code, la méthode de retard enregistrée sera accrochée à d'autres modules du noyau du navigateur pour le traitement. Lorsque la méthode de retard atteint la condition de déclenchement, c'est-à-dire que le temps de retard de jeu atteint l'ensemble, le module ajoutera la méthode à exécuter à la file d'attente de tâche du module. Ce processus est indépendant du fil principal du moteur d'exécution. Le moteur d'exécution extrait les tâches de la file d'attente de tâche du module en séquence pour exécuter lorsque la méthode du thread principal est exécutée et atteint l'état inactif. Le délai pendant cette période peut être supérieur au délai défini lors de l'enregistrement de la tâche;
Lorsque le navigateur est inactif, il essaiera constamment d'extraire les tâches de la file d'attente des tâches du module, qui est appelée le modèle de boucle d'événements;
Revenons sur le code précédent. Le temps de retard de la deuxième méthode de retard setTimeout () est de 10 millisecondes, ce qui est déclenché plus tôt que le premier! Pourquoi le résultat d'exécution est-il derrière? Parce qu'il a été bloqué par le code précédent pour environ 1000,5 ~ 1001 millisecondes (selon la vitesse de traitement du navigateur), lorsqu'il est accroché au module de traitement et lorsque le temps de déclenchement est ajouté à la file d'attente de tâches, la première méthode de retard Settimeout (), alors, vous devez comprendre, non?
Maintenant, si vous modifiez ce qui précède (nouvelle date - Démarrez <1000) {} à while (new Date - Start <189) {} ou while (nouvelle date - Démarrer <190) {}, quel est le résultat? Je ne dirai pas grand-chose! Actualisez le navigateur 20 fois chacun et voyez les résultats vous-même!
La méthode setInterval () et setTimeout () ont le même statut. Lorsque la méthode setInterval () est appelée, la méthode de retard enregistrée est accrochée au module pour le traitement. Chaque fois que l'heure de déclenchement arrive, la méthode à exécuter est ajoutée à la file d'attente de tâche une fois;
Jetons un coup d'œil à la syntaxe de Settimeout:
var timeId = window.setTimeout (func, retard, [param1, param2, ...]);
var timeId = window.setTimeout (code, retard);
setTimeout et setInterval sont des méthodes d'objets de fenêtre (la fenêtre peut être omise). Les deuxième paramètres facultatifs (non pris en charge par IE9 et Versions anciennes) sont les paramètres transmis à FUNC. Chaque fois qu'ils sont appelés, un ID numérique sera retourné (il est juste un nombre imprimé dans le navigateur, mais je l'ai imprimé dans WebStorm et j'ai constaté qu'il s'agit en fait d'un objet avec de nombreux attributs). Cet ID maintient les informations pertinentes de son Settimeout Settimeout ou SetInterval correspondant, et est principalement utilisé pour les effacer (ou les fermer) dans le module intermédiaire et la file d'attente de la tâche (en utilisant les méthodes ClearTimeout (ID) et ClearInterval (ID)).
Si vous devez transmettre un paramètre dans votre fonction de rappel, ce qui suit est la méthode d'écriture compatible IE
if (document.all &&! window.settimeout.ispolyfill) {var __natiVest__ = window.setTimeout; window.setTimeout = function (vCallback, ndelay, param1, param2, param3) {var aargs = array.prototype.slice.call (arguments, 2); return __natiVest __ (vCallback instanceOf function? function () {vCallback.Apply (null, aargs);}: vCallback, ndelay); }; window.settimeout.ispolyfill = true;}Une erreur commune se produit lors de l'utilisation des fermetures dans une boucle
pour (var i = 0; i <10; i ++) {setTimeout (function () {console.log (i);}, 1000);}Le code ci-dessus sortira le numéro 10 dix fois. Pourquoi? Fermeture!
Lorsque Console.log est appelé, bien que la fonction anonyme maintient une référence à la variable externe I, la boucle FOR s'est terminée à ce moment et la valeur de i est modifiée à 10.
Pour obtenir le résultat souhaité, une copie de la variable, je dois être créée dans chaque boucle.
Afin d'obtenir correctement le numéro de boucle, il est préférable d'utiliser un wrapper anonyme (en fait ce que nous appelons généralement des fonctions anonymes auto-exécutantes).
for (var i = 0; i <10; i ++) {(function (e) {setTimeout (function () {console.log (e);}, 1000);}) (i);}La fonction anonyme externe sera exécutée immédiatement et je serai utilisé comme paramètre. À l'heure actuelle, la variable E de la fonction aura une copie de i.
Lorsque la fonction anonyme transmise à Settimeout est exécutée, elle a une référence à E et cette valeur ne sera pas modifiée par la boucle.
Il existe une autre façon de faire le même travail; C'est pour renvoyer une fonction d'un wrapper anonyme. Cela fonctionne de la même manière que le code ci-dessus.
pour (var i = 0; i <10; i ++) {setTimeout ((fonction (e) {return function () {console.log (e);}}) (i), 1000)}Une autre application importante: la fonction de la fonction et le débouchement
Veuillez consulter certaines informations que j'ai collectées sur Internet:
JavaScript - fonction d'optimisation des performances accélérat et fonction
Lien de référence:
https://developer.mozilla.org/zh-cn/docs/web/api/window/settimeout
http://www.alloyteam.com/2015/10/turning-to-javascript-series-from-settimeout-said-the-event-loop-model/#prettyphoto
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.