Fermer

mars 13, 2024

Anti-rebond dans votre cadre

Anti-rebond dans votre cadre


L’anti-rebond est un moyen d’éviter les erreurs d’entrée et d’attendre que les choses se calment avant d’exécuter une fonction. Créez une fonction anti-rebond et réutilisez-la souvent.

Parfois, lorsque vous écrivez un programme, vous devez attendre quelques secondes avant de faire quoi que ce soit. C’est certainement le cas lors de la récupération, de la récupération et de la mise à jour des données. Vous pouvez avoir 50 déclencheurs à la fois, alors qu’il vous suffit d’un seul.

L’anti-rebond est un moyen d’éviter toutes ces erreurs d’entrée et d’attendre que les choses se calment. Alors, et alors seulement, la fonction attendue sera exécutée.

Minuteur

Le meilleur exemple et la meilleure façon de montrer l’anti-rebond est d’utiliser une minuterie. Disons que nous voulons exécuter la fonction getData() au moment opportun.

Étape 1 : définirTimeout

Nous devons d’abord attendre un bon moment, disons 5 secondes, avant d’exécuter la fonction.

setTimeout(() => console.log('5 seconds'), 5000);

Cela garantira que rien ne sera exécuté avant que 5 secondes ne s’écoulent. C’est génial, mais nous devrons peut-être annuler cela.

Étape 2 : effacer la minuterie

const timeout = setTimeout(() => console.log('5 seconds'), 5000);
clearTimeout(timeout);

Si nous exécutons ceci, cela nous permettra d’effacer le délai d’attente. Cela signifie que nous annulons l’exécution de la fonction à l’intérieur setTimeout Cependant, comme nous n’avons aucun mécanisme pour continuer, cela sera toujours résolu.

Étape 3 : Fonction

Ici, nous mettons le délai d’attente à l’intérieur d’une fonction. Si le délai d’attente existe, il sera effacé. Notez que nous devons déclarer le timeout variable en dehors du run fonctionner pour qu’il persiste. Sinon, il déclarerait simplement un nouveau délai d’attente à chaque fois et ne serait jamais annulé.

let timeout: NodeJS.Timeout;

const run = () => {
	clearTimeout(timeout);
	timeout = setTimeout(() => console.log('5 seconds'), 5000);
};

run();
run();
run();

Depuis run est exécuté trois fois de suite, le délai d’attente n’a pas le temps de se terminer. Il sera exécuté avant que 5 secondes ne se soient écoulées. Les deux premiers run les fonctions sont annulées et la troisième s’exécute comme prévu. C’est ce qui évite les appels superflus. C’est ce qu’on appelle le rebond.

Étape 4 : Anti-rebond

Si nous utilisons cette fonction une seule fois dans notre programme et que nous ne pensons jamais utiliser cette fonction à nouveau (très improbable pour un programmeur Web), alors nous pourrions simplement nous arrêter ici :

let timeout: NodeJS.Timeout;

const debounce = () => {
	clearTimeout(timeout);
	timeout = setTimeout(() => getData(), 5000);
};

debounce();
debounce();
debounce();

Cependant, nous briserions Single Responsibility Principal, où nous pourrions facilement en faire un module et réutilisable. J’ai découvert qu’après plus de 20 ans de programmation, c’est celui-ci qui me fait gagner le plus de temps.

Étape 5 : utiliserDebounce

Le problème avec la création d’un module réutilisable est la variable timeout. Nous devons nous assurer qu’il sera réutilisé. Nous ne voulons pas non plus repasser le délai d’attente et la fonction.

NE FAITES PAS CELA !!!

let timeout: NodeJS.Timeout;

	const getData = () => {
		console.log('getting data...');
	};

	const debounce = (func: () => void, waitfor: number) => {
		clearTimeout(timeout);
		timeout = setTimeout(() => func(), waitfor);
	};

	debounce(getData, 5000);
	debounce(getData, 5000);
	debounce(getData, 5000);

Nous avons donc besoin d’une fonction que nous pouvons importer, configurer nos variables, puis appeler quand et autant de fois que nous le souhaitons :

useDebounce.ts

export function useDebounce<F extends (...args: Parameters<F>) => ReturnType<F>>(
    func: F,
    waitFor: number,
): (...args: Parameters<F>) => void {
    let timeout: NodeJS.Timeout;
    return (...args: Parameters<F>): void => {
        clearTimeout(timeout);
        timeout = setTimeout(() => func(...args), waitFor);
    };
}

Nous pouvons importer cette fonction n’importe où et la réutiliser dans n’importe quel framework !

Étape 6 : Utilisation

import { useDebounce } from 'use-debounce';

const getData = () => {
	console.log('getting data...');
};

const debounce = useDebounce(getData, 5000);

debounce();
debounce();
debounce();

Comme vous pouvez le voir, nous obtenons du code réutilisable avec les mêmes résultats. Pas besoin de suivre les minuteries ou de repasser nos données.

Exemple

Sauvegarde automatique

Une utilisation peut-être pour la sauvegarde automatique des brouillons :

const saveDraft = () => {
   // save draft
};

const debounce = useDebounce(saveDraft, 5000);

...

<input type="text" oninput="debounce()" />

Vous verrez peut-être onchange ou onkeyup ici aussi. Ce serait le même modèle pour :

  • Suggestions de recherche au fur et à mesure que vous tapez
  • Saisie automatique de la liste déroulante

Ce serait généralement une bonne idée pour tout ce que vous devez également calculer. Si vous avez un jeu, vous ne souhaiterez peut-être pas recalculer la position jusqu’à ce qu’un joueur ait fini de bouger. Vous verrez de nombreux exemples avec les mouvements de la souris. Il existe une infinité de cas d’utilisation.

Autres notes

  • RXJS a un rebond utilisé pour les observables. C’est très bien lorsque vous souhaitez annuler un abonnement au fur et à mesure que vous en recevez davantage.
  • Lodash a cela intégré, mais je ne suis pas fan de l’importation de plus que ce dont vous avez besoin.

Faire fonctionner l’anti-rebond n’est pas toujours aussi simple qu’il y paraît. Vous devez déclarer une fonction qui renvoie une fonction. De plus, l’alignement des types dans TypeScript avec ESLint peut ne pas être aussi évident dans d’autres versions. J’ai essayé de donner une version qui peut fonctionner n’importe où.

L’anti-rebond est une nécessité pour tout programmeur intermédiaire ou supérieur. Utilisez et réutilisez cette fonction, et vous ne perdrez plus jamais de temps à y penser.




Source link