Maison >interface Web >js tutoriel >Utilisation intelligente de setTimeout dans les compétences JS Front-end throttling_javascript
Qu'est-ce que la limitation des fonctions ?
La limitation des fonctions signifie simplement que nous ne voulons pas que la fonction soit appelée en continu sur une courte période de temps. Par exemple, la chose la plus courante que nous faisons est que lorsque la fenêtre est zoomée, nous effectuons souvent d'autres fonctions d'opération, comme l'envoi d'une requête ajax, attendez, puis lorsque la fenêtre est zoomée, il est possible d'envoyer plusieurs requêtes en continu, ce qui n'est pas ce que nous voulons, ou notre effet commun de changement d'onglet consistant à déplacer la souris vers l'intérieur et l'extérieur, parfois en continu et très. rapidement. Parfois, il y aura un effet de scintillement. À ce moment-là, nous pouvons utiliser la limitation des fonctions pour fonctionner. Comme nous le savons tous, les opérations DOM seront très consommatrices ou affecteront les performances. Si un grand nombre d'opérations DOM sont liées aux éléments lors du zoom de la fenêtre, cela entraînera un grand nombre de calculs continus, par exemple sous IE. Des opérations DOM se produiront. L'opération affectera les performances du navigateur et provoquera même le blocage du navigateur dans les cas graves. À l'heure actuelle, nous pouvons utiliser la limitation des fonctions pour optimiser le code ~
Principes de base de la limitation des fonctions :
Utilisez d'abord une minuterie pour retarder l'exécution de la fonction. Par exemple, utilisez la fonction setTomeout() pour retarder l'exécution de la fonction pendant un certain temps, si d'autres événements sont déclenchés pendant cette période, nous pouvons l'utiliser. la méthode clearTimeout() Pour effacer le minuteur, définissezTimeout() un nouveau minuteur pour retarder l'exécution pendant un certain temps.
Récemment, une équipe est occupée sur un projet. Il existe une page comme celle-ci, qui est développée en mode traditionnel (se plaignant de la raison pour laquelle elle n'utilise pas React, elle a beaucoup d'opérations DOM et ses performances sont). relativement médiocre, surtout lorsque vous zoomez et dézoomez sur la fenêtre, c'est terrible. Quelque chose s'est produit, des décalages se sont produits ou même le navigateur est tombé en panne. Pourquoi?
Comme cette page comporte de nombreuses opérations DOM, l'exécution de la fonction sera déclenchée à chaque image lors du zoom de la fenêtre, et les opérations DOM seront répétées en continu, ce qui coûte très cher au navigateur. Puisque le navigateur recalculera le DOM lorsque la fenêtre est zoomée, pourquoi ne pouvons-nous pas retarder le calcul du DOM et laisser la fenêtre arrêter de zoomer avant de le recalculer ? Cela permettra d'économiser la surcharge du navigateur et d'obtenir déjà l'effet d'optimisation ?
Préparation aux connaissances
1. setTimeout(code,millisec) est bien sûr le protagoniste de cet article.
La méthode setTimeout() est utilisée pour appeler une fonction ou une expression calculée après un nombre spécifié de millisecondes.
le code est requis. La chaîne de code JavaScript à exécuter après la fonction à appeler.
millisec est requis. Le nombre de millisecondes à attendre avant d'exécuter le code.
Astuce : setTimeout() n'exécute le code qu'une seule fois. Si vous souhaitez l'appeler plusieurs fois, utilisez setInterval() ou demandez au code lui-même d'appeler à nouveau setTimeout().
Largement utilisé dans les minuteries, les carrousels, les effets d'animation, le défilement automatique, etc.
2. clearTimeout(id_of_setTimeout)
Le paramètre id_of_settimeout est la valeur ID renvoyée par setTimeout(). Cette valeur identifie le bloc de code d'exécution différée à annuler.
3. fun.apply(thisArg[, argsArray])
La méthode apply() appelle une fonction en spécifiant cette valeur et ses paramètres (les paramètres existent sous la forme d'un tableau ou d'un objet de type tableau)
La syntaxe de cette fonction est presque la même que celle de la méthode call(). La seule différence est que la méthode call() accepte une liste de paramètres, tandis que apply() accepte un tableau (ou un objet de type tableau) contenant plusieurs paramètres ).
Paramètres
thisArg
La valeur this spécifiée lorsque la fonction amusante est en cours d'exécution. Il est à noter que la valeur this spécifiée n'est pas nécessairement la valeur réelle this lorsque la fonction est exécutée. Si la fonction est en mode non strict, elle pointera automatiquement vers l'objet global (objet fenêtre dans le navigateur) lorsqu'elle l'est. spécifié comme null ou undefined. ), et celui dont la valeur est une valeur primitive (nombre, chaîne, valeur booléenne) pointera vers l'objet d'encapsulage automatique de la valeur primitive.
argsArray
Un tableau ou un objet de type tableau, dont les éléments du tableau seront transmis en tant que paramètres distincts à la fonction fun. Si la valeur de ce paramètre est nulle ou indéfinie, cela signifie qu'aucun paramètre ne doit être transmis. À partir d'ECMAScript 5, des objets de type tableau sont disponibles.
Lorsque vous appelez une fonction existante, vous pouvez spécifier un objet this pour celle-ci. this fait référence à l'objet actuel, qui est l'objet qui appelle cette fonction. En utilisant apply, vous pouvez écrire la méthode une fois, puis en hériter dans un autre objet, sans avoir à écrire la méthode à plusieurs reprises dans le nouvel objet.
4. fun.call(thisArg[, arg1[, arg2[, ...]]])
Cette méthode appelle une fonction ou une méthode en utilisant une valeur spécifiée et plusieurs valeurs de paramètres spécifiées.
Paramètres
thisArg
La valeur this spécifiée lorsque la fonction amusante est en cours d'exécution. Il est à noter que la valeur this spécifiée n'est pas nécessairement la valeur this réelle lorsque la fonction est exécutée. Si la fonction est en mode non strict, la valeur this spécifiée comme nulle et indéfinie pointera automatiquement vers l'objet global (dans le navigateur, c'est un objet fenêtre), et celui dont la valeur est une valeur primitive (nombre, chaîne, valeur booléenne) pointera vers l'objet d'encapsulage automatique de la valeur primitive.
arg1, arg2, ...
La liste des paramètres spécifiés.
Lors de l'appel d'une fonction, vous pouvez attribuer un autre objet à cet objet. ceci fait référence à l'objet actuel, le premier paramètre de la méthode d'appel. Grâce à la méthode d'appel, vous pouvez emprunter des méthodes sur un objet à un autre objet, comme Object.prototype.toString.call([]), qui est un objet Array empruntant des méthodes sur l'objet Object.
Fonction :
Utilisez la méthode call pour appeler le constructeur parent
Utilisez la méthode call pour appeler des fonctions anonymes
Utilisez la méthode call pour appeler une fonction anonyme et spécifiez le 'this' du contexte
Une digression ici :
apply est très similaire à call(), la différence réside dans la façon dont les paramètres sont fournis. apply utilise un tableau d'arguments plutôt qu'une liste d'arguments. apply peut utiliser des littéraux de tableau, tels que fun.apply(this, ['eat', 'bananas']), ou des objets de tableau, tels que fun.apply(this, new Array('eat', 'bananas' )). Vous pouvez également utiliser des objets arguments comme paramètres argsArray. les arguments sont des variables locales d'une fonction. Il peut être utilisé comme n'importe quel paramètre non spécifié de l'objet appelé. De cette façon, vous n'avez pas besoin de connaître tous les paramètres de l'objet appelé lorsque vous utilisez la fonction apply. Vous pouvez utiliser des arguments pour transmettre tous les arguments à l'objet appelé. L'objet appelé est alors chargé du traitement de ces paramètres.
À partir de la version 5 d'ECMAScript, vous pouvez utiliser n'importe quel type d'objet de type tableau, c'est-à-dire à condition qu'il ait une propriété de longueur et une propriété entière comprise dans la plage [0...longueur). Par exemple, vous pouvez désormais utiliser NodeList ou un objet auto-défini similaire à {'length' : 2, '0' : 'eat', '1' : 'bananas'}.
La différence entre les méthodes call et apply est qu'à partir du deuxième paramètre, les paramètres de la méthode call seront transmis à la méthode empruntée en tant que paramètres, tandis que apply place directement ces paramètres dans un tableau puis les transmet, et enfin le liste des paramètres de la méthode empruntée C'est pareil.
Scénario d'application : call peut être utilisé lorsque les paramètres sont clairs, et apply peut être utilisé pour combiner des arguments lorsque les paramètres ne sont pas clairs
Donnez maintenant un exemple
Comme nous le savons tous, onscolll, onresize, etc. sont très gourmands en performances et les nombres sont imprimés lorsque la fenêtre est zoomée.
var count = ; window.onresize = function () { count++; console.log(count); }
Rétractez et rétractez la taille de la fenêtre du navigateur dans le navigateur Chrome, imprimez comme suit
Ce n'est évidemment pas ce que nous voulons. Si nous passons à une requête ajax, la fenêtre sera zoomée une fois et plusieurs requêtes ajax seront déclenchées successivement. Essayons d'utiliser la limitation de fonction, bien sûr, ajoutez simplement un settimeout(. ) minuterie,
La première méthode d'emballage
var count = ; function oCount() { count++; console.log(count); } window.onresize = function () { delayFun(oCount) }; function delayFun(method, thisArg) { clearTimeout(method.props); method.props = setTimeout(function () { method.call(thisArg) }, ) }
La deuxième méthode d'emballage
Construisez une fermeture et utilisez la fermeture pour former une portée privée pour stocker la minuterie. La minuterie est introduite en passant des paramètres.
var count = ; function oCount() { count++; console.log(count); } var funs= delayFun(oCount,); window.onresize = function () { funs() }; function delayFun(func, wait) { var timer = null; return function () { var context = this, args = arguments; clearTimeout(timer); timer = setTimeout(function () { func.apply(context, args); }, wait) }; }
Optimisez la deuxième méthode et les performances seront meilleures
Ceci renvoie une fonction qui ne sera pas exécutée si elle est appelée sans interruption. La fonction ne sera exécutée que lorsqu'elle sera à nouveau appelée N millisecondes après la fin de son appel. Si le paramètre « immédiat » est passé, la fonction sera planifiée immédiatement dans la file d'attente d'exécution, sans délai.
function delayFun (func, wait, immediate) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); }; }; // 用法 var myEfficientFn = delayFun (function() { // 所有繁重的操作 }, ); window.addEventListener('resize', myEfficientFn);
La fonction ne permet pas à la fonction de rappel d'être exécutée plus d'une fois dans le délai spécifié. Cette fonction est particulièrement importante lors de l'attribution d'une fonction de rappel à un événement qui sera déclenché fréquemment.
setTimeout est si puissant, pouvons-nous l'utiliser largement dans des projets ?
Personnellement, je ne le recommande pas. Dans notre métier, il est fondamentalement interdit d'utiliser setTimeout dans la logique métier, car la plupart des méthodes d'utilisation que j'ai vues sont des problèmes faciles à résoudre, et setTimeout est utilisé comme un hack.
Par exemple, lorsqu'une instance n'a pas été initialisée, nous utilisons cette instance. La mauvaise solution est d'ajouter un setTimeout lors de l'utilisation de l'instance pour garantir que l'instance est initialisée en premier.
Pourquoi est-ce faux ? C'est en fait la méthode d'utilisation des hacks
La première est de tendre un piège et de perturber le cycle de vie du module
La seconde est que lorsqu'un problème survient, setTimeout est en fait difficile à déboguer.
Je pense que la bonne façon de l'utiliser est d'examiner le cycle de vie (veuillez vous référer à "À propos du cycle de vie du logiciel") et de mentionner l'instanciation avant utilisation.
Concernant l'utilisation intelligente de setTimeout dans JS et la limitation des fonctions front-end, l'éditeur vous le présentera ici, j'espère que cela vous sera utile !