Maison > Article > interface Web > Utilisation intelligente de setTimeout dans la limitation des fonctions frontales JS
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 en exécutons souvent une autre. fonctions d'opération, telles que l'envoi d'une requête ajax et d'autres choses, 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 mouvement commun de la souris dans et hors effet de changement d'onglet, parfois continu et en mouvement Bientôt, il y aura un effet de scintillement. À ce moment-là, nous pouvons utiliser la fonction de limitation 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 ~
Le principe de base de la limitation des fonctions :
Utilisez une minuterie pour retarder d'abord 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 utiliser la méthode clearTimeout() pour effacer le minuteur, puis setTimeout() un nouveau. timer. Le serveur retarde l’exécution pendant un moment.
Récemment, une équipe est occupée sur un projet. Il existe une telle page, qui est développée en mode traditionnel (se plaignant de la raison pour laquelle elle n'utilise pas React). Elle contient de nombreuses opérations DOM, et ses). les performances sont relativement médiocres, surtout lorsque vous effectuez un zoom avant et arrière sur la fenêtre. Parfois, quelque chose de terrible se produit, il se bloque ou même le navigateur plante. Pourquoi?
Comme cette page contient beaucoup d'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 à l'utilisateur. 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 des 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. La méthode fun.apply(thisArg[, argsArray])
apply() spécifie cette valeur et ces paramètres (les paramètres sont sous forme de tableaux ou de tableaux- comme des objets Appeler une fonction
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() l'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.
Lors de l'appel d'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 utilise une valeur spécifiée et appelle un fonction ou méthode avec plusieurs valeurs de paramètres spécifiées
Parameters
thisArg
lorsque la fonction amusante est en cours d'exécution. Cette valeur est spécifiée. 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 d'appel pour appeler le constructeur parent
Utilisez la méthode d'appel pour appeler la fonction anonyme
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 est que Comment fournir les paramètres. 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 tant qu'il a une propriété de longueur et une propriété entière 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 à leur tour, tandis que apply place directement ces paramètres dans un tableau. puis les transmet. Enfin, la liste des paramètres de la méthode empruntée est la même
Scénarios d'application : lorsque les paramètres sont clairs, l'appel peut être utilisé, et lorsque les paramètres ne sont pas clairs, apply peut. être utilisé pour appliquer les arguments
Donnez maintenant un exemple
Comme nous le savons tous, onscoll, onresize, etc. sont très gourmands en performances, et les nombres sont imprimés lorsque la fenêtre est mise à l'échelle.
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
Ceci est évidemment pas nous. Si nous le voulons, si nous passons à une requête ajax, la fenêtre sera mise à l'échelle une fois et plusieurs requêtes ajax seront déclenchées en continu. Essayons d'utiliser la limitation de fonction, bien sûr, ajoutons un timer settimeout() Très bien,
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
Construire une fermeture et utilisez la fermeture pour former une portée privée pour stocker le minuteur. Le minuteur est introduit 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, les performances seront meilleures
Ici renvoie une fonction, Si elle est appelé sans interruption, il ne sera pas exécuté. 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. La fonction
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);
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 posent des problèmes faciles à résoudre. 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 ? Voici 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 très difficile à déboguer.
Concernant l'utilisation intelligente de setTimeout dans JS et la limitation des fonctions frontales, l'éditeur vous le présentera ici, j'espère que cela vous sera utile !
Pour une utilisation plus intelligente de setTimeout dans JS et des articles connexes sur la limitation des fonctions frontales, veuillez faire attention au site Web PHP chinois !