JS interview question - anti shake and throttling

Posted by dotsc on Fri, 04 Feb 2022 10:44:51 +0100

1, Anti shake

Problem scenario: sometimes we encounter such a situation, such as searching in a search box. Without function anti shake, when we modify the value in the input box, what we want is to wait until we complete the input before performing the search for the input keyword. Here, problems begin to appear, such as the following example.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script>
    window.onload = function() {
      // Simulate the ajax request, and the content to be searched is passed in
      let count = 0;
      function ajax(params) {
        console.log('This is the second'+(++count)+'Request, the content is:'+params);
      }
      // Binding input box
      let search = document.getElementById('serach');
      search.onkeyup = function(e) {
        //Call ajax
        ajax(e.target.value)
      }

    }
  </script>
</head>
<body>
  <div>
    <span>Please enter the search content</span>
    <input id="serach" type="text">
  </div>
</body>
</html>

It can be seen that we trigger many events in a short time, resulting in continuous calls to ajax, but the last request is what we need, which is called a waste of resources. Therefore, we must eliminate this phenomenon through the anti shake function.

Principle and concept: the callback is executed n seconds after the event is triggered. If it is triggered again within this n seconds, it will be timed again.

Code implementation:

<script>
    window.onload = function() {
      // Simulate the ajax request, and the content to be searched is passed in
      let count = 0;
      function ajax(params) {
        console.log('This is the second'+(++count)+'Request, the content is:'+params);
      }

       // func is the function executed by the user, and wait is the waiting time
       const debounce = (func,wait = 100) => {
        // Cache a timer
        let timer = 0;
        // The function returned is the anti shake function of each call
        return function(...args) {
          // If the timer has been started, then this is to clear the last timer
          if(timer) {
            clearTimeout(timer);
          }
          // If not, define a new timer to extend the method passed in by the user
          timer = setTimeout(() => {
            func.apply(this,args);
          },wait)
        }
      }

      // Binding input box
      let search = document.getElementById('serach');
      // Bind anti shake function to ajax
      let debounceA = debounce(ajax,1000);
      search.onkeyup = function(e) {
        // Call ajax with anti shake function
        // ajax(e.target.value)
        debounceA(e.target.value)
      }
      
    }
  </script>

As you can see, because the waiting time I input is 1s, the request will be sent only when the input stops and the keyboard time is not triggered for more than one second. Here, the anti shake function is realized. (in button submission, in order to prevent multiple button submissions, the form verification can use the anti shake function)

2, Throttling

Problem scenario: when we are in Baidu, for example, we need to search a person's information - Lu · the guardian of the cat · asthma conqueror · the person selected by the light · di. It is reasonable that such a long name may not be remembered, but the anti shake function will delay the search. If this time is very long (3s), the user could find it accurately by inputting Lu · cat, However, the information can only be given after 3s, which will greatly affect the user experience. Some small partners may think that I can directly reduce the delayed execution value in the anti shake function? This is OK, but it will cause the applicability of the anti shake function to be small and very inflexible, so another method - throttling is needed.

Principle concept: it is stipulated that the function can only be triggered once in a unit time. If this function triggers multiple times in time, only one is valid. Similar to the anti shake function.

Code implementation:

  <script>
    window.onload = function() {
      // Simulate the ajax request, and the content to be searched is passed in
      let count = 0;
      function ajax(params) {
        console.log('This is the second'+(++count)+'Request, the content is:'+params+' '+new Date().getSeconds());
      }

       // func is the function executed by the user, and wait is the waiting time
       const throttle  = (func,wait = 100) => {
        // The last time the function was executed
        let lastTime = 0;
        // The function returned is the anti shake function of each call
        return function(...args) {
          // current time 
          let now = +new Date();
          // If the difference between the current time and the last execution time is greater than the waiting time, the function is executed
          if(now - lastTime > wait) {
            lastTime = now;
            func.apply(this,args);
          }
        }
      }
   
      // Binding input box
      let search = document.getElementById('serach');
      // Bind anti shake function to ajax
      let throttleA = throttle(ajax,1000);
      search.onkeyup = function(e) {
        // Call ajax with anti shake function
        // ajax(e.target.value)
        throttleA(e.target.value)
      }
      
    }
  </script>

It can be seen that the delay time set by the throttling function is 1s. No matter how many keyboard events we trigger in this 1s, the ajax request will be executed only once. (in the drag and drop of the picture, not using throttling will cause jamming, and using throttling will lead to many processes)

Topics: Javascript Front-end