In the last article I wrote the anti-shake function, now to write the throttling function, because the two functions are similar, use scenarios also overlap, so the two articles are written in tandem, but what is the difference between the two?

Simple understanding:

Image stabilization function can be carried in event just after the point or wait for a period of time after the trigger our binding function, and throttle function is found of knowledge meaning, in event fires, binding function is executed, but the frequency of execution is limited, therefore, in the era of the event is always triggered every once in a while a binding function to perform.

Each time a function is called, clearTimeout is used to terminate the previous timer, and then a timer is bound again. Can the throttling function do this? Anyway, let’s try it first!! (It is suggested to read the following article after checking my previous anti-shake function. However, it doesn’t matter if I haven’t seen the last article. It should be easy to understand, but if I haven’t understood it, this must be the reason.)

1. setTimeout

Let’s start with an example that listens for mouse movement events, with the following HTML code

<! DOCTYPEhtml>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>xhx</title>
  <style>
    .box {
      width: 300px;
      height: 300px;
      background-color: green;
      font-size: 40px;
      text-align: center;
    }
  </style>
</head>

<body>
  <div class="box" id="box">

  </div>
</body>
<script>
  let box = document.getElementById('box');
  let count = 0;
  const MouseMove = () = > {
    console.log("send a request message");
    console.log("consume cpu");
    count++;
    box.innerHTML = count;
  }
  box.addEventListener("mousemove", MouseMove)
</script>

</html>
Copy the code

Now to throttle the mouse movement events, we will execute the bound function every 1000ms while the mouse events continue to fire

// First version of the code<! DOCTYPEhtml>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>xhx</title>
  <style>
    .box {
      width: 300px;
      height: 300px;
      background-color: green;
      font-size: 40px;
      text-align: center;
    }
  </style>
</head>

<body>
  <div class="box" id="box">

  </div>
</body>
<script>
// throttling function
  function throttle(func, wait){
    var timeout;
    return function(){
      const _this = this;
      const args = arguments;
      if(! timeout){ timeout =setTimeout(function(){
          func.apply(_this, args);
          timeout = null;
        }, wait)
      }
    }
  }

  let box = document.getElementById('box');
  let count = 0;
  const MouseMove = () = > {
    console.log("send a request message");
    console.log("consume cpu");
    count++;
    box.innerHTML = count;
  }
  box.addEventListener("mousemove", throttle(MouseMove, 1000))
</script>

</html>

Copy the code

All of this is easy to understand, so let’s look at the animation

Now that we have throttled using setTimeout, we have taken the first step and are halfway there, let’s try an easier way to throttle using timestamps

2. The timestamp

In the above code, all you need to do is change the throttle, which is slightly different from the above. This will trigger the binding function upon entry, and will not trigger the function when the mouse moves out of the window. SetTimeout will trigger the binding function again when the mouse moves out of the window

/ / the second edition
  function throttle(func, wait){
    let nowTime;
    let lastTime = 0;
    return function(){
      const _this = this;
      const args = arguments;
      nowTime = +new Date(a);// +new Date() = new Date().getTime()
      if(nowTime - lastTime > wait){ // Fires if one wait has elapsed since the last event
        func.apply(_this, args)
        lastTime = nowTime // Set the current time to the last time of the next time}}}Copy the code

So far, we have used two methods to implement the throttling function, but there are some problems, which is also the difference between the two mentioned above. SetTimeout can be executed once after the trigger is stopped, while the timestamp can be executed once at the beginning of the trigger. Now can we implement both the trigger at the beginning of the trigger, What about functions that can fire once after completion? So we have our third version of the function

3. SetTimeout + timestamp

This is going to be a little bit more difficult for me, but I’ll try to describe it in detail

/ / the third edition<script>
  // throttling function
  function throttle(func, wait) {
    let nowTime;     // The current time
    let lastTime = 0; // Last time
    let timeout;      / / timer
    let remainTime = 0;// The time remaining until the next call to the binding function

    return function () {
      const _this = this;
      const args = arguments;
      nowTime = +new Date(a);// nowTime is always the current timestamp
      remainTime = wait - (nowTime - lastTime);
      / / remainTime > wait is to prevent the system time change, because + new Date () is the system time, does not affect the overall situation the reader can delete "| | remainTime > wait"
      if (remainTime <= 0 || remainTime > wait) { // remainTime <= 0 = remainTime = remainTime = remainTime = remainTime = remainTime = remainTime = remainTime = remainTime
        if (timeout) {
          clearTimeout(timeout);
          timeout = null;
        }
        func.apply(_this, args);
        lastTime = nowTime;
        timeout = null;
      } else if(! timeout) {// Execute again after the event by this judgment
        timeout = setTimeout(() = > {
          func.apply(_this, args);
          lastTime = nowTime;
          timeout = null; }, remainTime); }}}let box = document.getElementById('box');
  let count = 0;
  const MouseMove = () = > {
    console.log("send a request message");
    console.log("consume cpu");
    count++;
    box.innerHTML = count;
  }
  box.addEventListener("mousemove", throttle(MouseMove, 1000))
</script>
Copy the code

The effect animation is shown below

4. More

The underscore throttling function can also pass in the option option, and we specify which effect the passed value has:

Leading: false Disables the first execution

Trailing: false disables the stop-triggered callback

There is no doubt that the code is gradually optimized, and as a learner, there is a cost of time to learn anything. Now that we have figured out the principle, we should give a thumbs up to ourselves for reading this, and give a thumbs up to our children for writing this!!

In fact, we can also have an cancel function, but I did that in the last article in the anti-shake function, so I won’t go into it here

If this article is useful to you, please give your kids a thumbs up!

Thank you for the JavaScript special that follows the Underscore articles, as well as a series of articles