[ Web Proxy ]
URL:
Viewing: https://fr.javascript.info/task/throttle [Back]  [Original]

Dcorateur d'acclration
FR

Nous souhaitons rendre ce projet open source disponible pour les gens du monde entier.

Aidez-nous traduire le contenu de ce tutoriel dans votre langue!

    Rechercher sur Javascript.info:
    Rechercher dans le tutoriel:
    Light themeDark theme
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek
    retour au cours

    Dcorateur d'acclration

    importance: 5

    Crez un dcorateur dacclration throttle(f, ms) qui retourne un wrapper.

    Lorsquil est appel plusieurs fois, il passe lappel f au maximum une fois par ms millisecondes.

    La diffrence avec debounce est que cest un dcorateur compltement diffrent :

    • debounce excute la fonction une fois aprs la priode de cooldown. Bon pour traiter le rsultat final.
    • throttle ne lexcute pas plus souvent que le temps donn en ms. Bon pour les mises jour rgulires qui ne devraient pas tre trs frquentes.

    En dautres termes, throttle est comme une secrtaire qui accepte les appels tlphoniques, mais qui drange le patron (appellez le f rel) pas plus dune fois par ms millisecondes.

    Examinons lapplication relle pour mieux comprendre cette exigence et voir do elle vient.

    Par exemple, nous voulons suivre les mouvements de la souris.

    Dans le navigateur, nous pouvons configurer une fonction excuter chaque mouvement de la souris et obtenir lemplacement du pointeur mesure quil se dplace. Pendant une utilisation active de la souris, cette fonction est gnralement utilise trs souvent et peut atteindre 100 fois par seconde (toutes les 10 ms). Nous aimerions mettre jour certaines informations sur la page Web lorsque le pointeur se dplace.

    Mais la mise jour de la fonction update() est trop lourde pour tous les micro-mouvements. Il est galement inutile de mettre jour plus dune fois toutes les 100 ms.

    Nous allons donc lenvelopper dans le dcorateur : utilisez throttle(update, 100) comme fonction excuter chaque dplacement de souris la place de update() dorigine. Le dcorateur sera appel souvent, mais update() sera appel au maximum une fois toutes les 100 ms.

    Visuellement, cela ressemblera ceci:

    1. Pour le premier mouvement de souris, la variante dcore passe lappel update. Cela est important, lutilisateur voit notre raction leur mouvement immdiatement.
    2. Puis, alors que la souris continue davancer, il ne se passe plus rien jusqu 100ms. La variante dcore ignore les appels.
    3. la fin de 100ms une autre update se produit avec les dernires coordonnes.
    4. Enfin, la souris sarrte quelque part. La variante dcore attend que 100ms expire, puis lance update avec les dernires coordonnes. Donc, peut-tre le plus important, les coordonnes finales de la souris sont traites.

    Un exemple de code:

    function f(a) {
      console.log(a);
    }
    
    // f1000 passe les appels  f au maximum une fois toutes les 1000 ms
    let f1000 = throttle(f, 1000);
    
    f1000(1); // montre 1
    f1000(2); // (tranglement, 1000ms pas encore coule)
    f1000(3); // (tranglement, 1000ms pas encore coule)
    
    // quand 1000ms expirent...
    // ...sort 3, la valeur intermdiaire 2 a t ignore

    P.S. Les arguments et le contexte this transmis f1000 doivent tre transmis f dorigine.

    Open a sandbox with tests.

    solution
    function throttle(func, ms) {
    
      let isThrottled = false,
        savedArgs,
        savedThis;
    
      function wrapper() {
    
        if (isThrottled) { // (2)
          savedArgs = arguments;
          savedThis = this;
          return;
        }
        isThrottled = true;
    
        func.apply(this, arguments); // (1)
    
        setTimeout(function() {
          isThrottled = false; // (3)
          if (savedArgs) {
            wrapper.apply(savedThis, savedArgs);
            savedArgs = savedThis = null;
          }
        }, ms);
      }
    
      return wrapper;
    }

    Un appel throttle(func, ms) retourne wrapper.

    1. Lors du premier appel, le wrapper excute simplement func et dfinit ltat de charge (isThrottled = true).
    2. Dans cet tat, tous les appels sont mmoriss dans savedArgs/savedThis. Veuillez noter que le contexte et les arguments sont dgale importance et doivent tre mmoriss. Nous avons besoin deux simultanment pour reproduire lappel.
    3. Aprs ms millisecondes, setTimeout se dclenche. Ltat de charge est supprim (isThrottled = false), et si nous avions ignor les appels, alors wrapper est excut avec les derniers arguments et contextes mmoriss.

    La 3me tape nexcute pas func, mais wrapper, car nous devons non seulement excuter func, mais encore une fois entrer dans ltat de charge et configurer le dlai dexpiration pour le rinitialiser.

    Ouvrez la solution avec des tests dans une sandbox.


    Web Proxy Viewer  |  New URL  |  Original Page