“This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!”

Promises:

Throttling is like drinking water and going to the toilet… Emm let’s try another example…

Like eating. The instructions say you eat every five hours. After one meal, the dog bounced for five hours. Five hours later, the dog comes back to eat. And so on, coming back every five hours to eat.

Said one words:

Definition: A function is executed once per unit of time if the event is fired continuously.

Throttling appearance:

<! -- < script SRC = "https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js" > < / script > -- >
<script src="https://cdn.jsdelivr.net/npm/[email protected]/underscore-umd-min.js"></script>
<div class="box"></div>
<script>
let obox = document.querySelector('.box')
function todo(e) {
  console.log(this, e);
}
let throttleFn = _.throttle(todo, 1000)
obox.onmousemove = throttleFn
</script>
Copy the code

We can see how the throttling works directly using the throttling functions in lodash.js or underscore. Js. I kept moving my mouse around in the div, and the throttles were printed every once in a while.

Remove the mask and see the truth

It’s not enough for us to know what it is; We need to know why! As usual, let’s teach ourselves a lesson!

For the throttling function, the parameters are similar to those for damping. It takes three arguments: the function fn that executes the stream; Milliseconds to be delayed wait; The third argument, options, disables the first execution by passing {leading: false}, and disables the last execution by {trailing: false}.

So according to the third, you can pass two property parameters. Three things can happen:

  • The first time is executed first and the last time is not executed
  • If you do not execute the first time, execute the last time
  • The first time you execute it, the last time you execute it

Have a head

The first time is executed first.

function throttle(fn, wait) {
  let previous = 0
  return function (. args) {
    let now = new Date().getTime() || Date.now()
    if (now - previous > wait) {
      fn.apply(this, args)
      previous = now
    }
  }
}
Copy the code

We can use the timestamp method to implement the first trigger first execution. The default time point (0 to start with) is recorded, and the current timestamp is obtained when the function is executed. When the interval is greater than the wait time, the fn function is executed. This ensures that the first trigger is executed first. But be sure to assign the value that records the current point in time to the default point in time, otherwise the function will always be triggered by mouse movement.

Have a tail

Executes at the end of the time range.

function throttle(fn, wait) {
  let timer = null
  return function (. args) {
    if (timer) return
    timer = setTimeout(() = > {
      fn.apply(this, args)
      timer = null
    }, wait)
  }
}
Copy the code

Consider the case of execution at the tail. Think of the timer setTimeout, which triggers execution at regular intervals. If you just came in, and it’s within the time interval of the last execution, you just return. Execute the function only when the scheduled time (no timer, just to execute) is reached, but remember to clear the timer when the execution is complete, so as not to delay the next event firing.

It has a head and a tail

Hey, it’s just like being a human being. It starts and ends! The head and tail are judged according to the third parameter. Then the time stamp version and the timer version of both east and west to make up, the general model out of the pull.

function throttle(fn, wait, options) {
  let previous = 0
  let timer = null
  return function (. args) {
        let now = Date.now()
        / / perform first
        // Select * from leading; // Select * from leading
        if(! previous && options.leading ===false) previous = now // If options.leading is postexecution, ignore when determining the time interval
        if (now - previous > wait) {
          if (timer) {
            clearTimeout(timer)
            timer = null
          }
          fn.apply(this, args)
          previous = now
        }
        / / after the implementation
        if(! timer && options.trailing) {// No timer
          timer = setTimeout(() = > {
            // Select * from 'leading' where 'leading' = 'leading'
            previous = options.leading ? Date.now() : 0
            fn.apply(this, args)
            timer = null
          }, wait)
        }
      }
  console.log(previous);
}
let obtn = document.querySelector('#btn')
let obox = document.querySelector('.box')  / / button
function todo(e) {
  console.log(this, e);
}
let throttleFn = throttle(todo, 1000, { leading: false.trailing: false })
obox.onmousemove = throttleFn
Copy the code

Add some decoration

The above calculation has basically completed the implementation of throttling. In addition, similar to shaking, there is the ability to execute a function with the result of a return value and to cancel throttling.

For return values, you can use a variable to receive the return value of the executing function. Unthrottling adds an unthrottling function to the function (unthrottling clears the timer and sets the start time to 0).

function throttle(fn, wait, options) {
  let timer = null, previous = 0, result
  let throttled = function (. args) {
    let now = Date.now()
    if(! previous && options.leading ==false) previous = now
    if (now - previous > wait) {
      if (timer) {
        clearTimeout(timer)
        timer = null
      }
      result = fn.apply(this, args)
      previous = now
    }
    if(! timer && options.trailing) { timer =setTimeout(() = > {
        previous = options.leading ? Date.now() : 0
        result = fn.apply(this, args)
        timer = null
      }, wait);
    }
    return result
  }
  throttled.cancel = function () {
    if (timer) clearTimeout(timer)
    timer = null
    previous = 0
  }
  return throttled
}
Copy the code

If you want to synchronize results, you can use promises, which are skipped here.

What’s the use of

The main purpose of throttling is to control an event that is frequently triggered to be requested once in a while.

  • Click the mouse continuously to trigger (only triggered once per unit time)
  • Scroll monitor, scroll to the bottom to see if there are more loads
  • Input listener (throttling and shaking)

Throttling anti-shake difference

Both damping and throttling reduce the frequency of user calls. Shake – off: for a period of time, the mouse has been constantly moving, based on the last function execution (after execution). Will be triggered multiple times, the last one prevail. Throttling: Execute a function for a period of time, and then execute the function for a period of time. Instead of firing multiple times, it fires at regular intervals.

MTV

If a man has no dream, what is the difference between him and a salted fish?