In-depth understanding of JavaScript - anti-shake and throttling

Anti-shake and throttling are both applications of closures. First understand the closure, and then understand the bold style of anti-shake and throttling

Anti-shake (debounce)

Leaving aside the concept, according to my own understanding, there is an anti-shake mechanism in the SLR. Because people will shake their hands when holding a SLR (SLR is heavy), the moment the shutter is pressed, the photo will be blurred, so there is an anti-shake mechanism to prevent novices from taking blurred photos

The anti-shake in the SLR is to prevent shaking, so that people can take clear photos. What is the anti-shake in JavaScript?

In the same way, its role is to prevent jitter. Imagine that when you trigger an event frequently, it will cause unnecessary performance loss, then let the event trigger after stopping triggering, so as to reduce some performance

Definition of anti-shake

Anti-shake is to delay the execution. You have been operating the trigger event and have not executed it. When you stop the operation, wait for how many seconds before executing it. That is to say,
no matter how high the event trigger frequency is, it must be executed n seconds after the event is triggered. If the event is triggered again n seconds after the event is triggered, the event of the new event shall prevail and be executed after n seconds. In short, it will not execute until you trigger the event and do not trigger the event within n seconds

Handwriting anti-shake

According to the definition, we know that it will be executed after n seconds, so we use a timer to implement it

function debounce(event, wait) {
    
    
  let timer = null;
  return function (...args) {
    
    
    clearTimeout(timer); // 清除setTimeout,使其回调函数不执行
    timer = setTimeout(() => {
    
    
      event.apply(this, args);
    }, wait);
  };
}

The code is very simple, that is, when the event is still being triggered, the timer is cleared so that it will be executed after n seconds, but this writing method will not be executed immediately for the first time, for its robustness, it is necessary to add a third step to judge whether it is executed for the first time A parameter flag to judge whether it is executed immediately

function debounce(event, wait, flag) {
    
    
  let timer = null;
  return function (...args) {
    
    
    clearTimeout(timer);
    if (!timer && flag) {
    
    
      event.apply(this, args);
    } else {
    
    
      timer = setTimeout(() => {
    
    
        event.apply(this, args);
      }, wait);
    }
  };
}

Anti-shake scene

Window size change, adjust style

window.addEventListener('resize', debounce(handleResize, 200));

Search box, search 1000ms after typing

debounce(fetchSelectData, 300);

Form validation, validate after 1000 milliseconds entered

debounce(validator, 1000);

Stabilizer Library

The two major tool libraries have anti-shake source code for reference

lodash-debounce

underscore-debounce

throttle

As the name implies, the section-by-section flow is like controlling a water valve. During the continuous triggering of the event, an event is executed within a fixed period of time.

handwriting throttling

Because the time is executed once in a fixed time, we have two implementation methods, one uses timestamp, and the other uses timer

timestamp

function throttle(event, wait) {
    
    
  let pre = 0;
  return function (...args) {
    
    
    if (new Date() - pre > wait) {
    
    
      // 当 n 秒内不重复执行
      pre = new Date();
      event.apply(this, args);
    }
  };
}

Although throttling can be achieved by using timestamps, the last event will not be executed

timer

function throttle(event, wait) {
    
    
  let timer = null;
  return function (...args) {
    
    
    if (!timer) {
    
    
      timer = setTimeout(() => {
    
    
        timer = null;
        event.apply(this, args);
      }, wait);
    }
  };
}

Use a timer to achieve throttling. Although it can be triggered last time, it will not be triggered for the first time.

Timestamp + timer

In order to solve the problem that both the first and the last time can be triggered, combine the two

function throttle(event, wait) {
    
    
  let pre = 0,
    timer = null;
  return function (...args) {
    
    
    if (new Date() - pre > wait) {
    
    
      clearTimeout(timer);
      timer = null;
      pre = new Date();
      event.apply(this, args);
    } else {
    
    
      timer = setTimeout(() => {
    
    
        event.apply(this, args);
      }, wait);
    }
  };
}

Throttling scene

scroll scroll

window.addEventListener('scroll', throttle(handleScroll, 200));

input dynamic search

throttle(fetchInput, 300);

Throttle Toolkit

lodash-throttle

underscore-throttle

Summarize

Anti-Shake: Execute only the last time. The event continues to trigger, but the function is only executed after n seconds after the event stops triggering

Throttling: Controls the frequency of execution. Trigger continuously, execute the function every n seconds

comparison chart
insert image description here

Online demo (Situ Zhengmei's demo) : anti-shake throttling

Guess you like

Origin blog.csdn.net/m0_66504310/article/details/128882781
Recommended