preface

Today our topic is the front end of the anti – shake and throttling, this topic has been a classic problem, the basic interview will meet, there are a lot of articles to write about this topic, so today we also take stock of this topic ~

PS: Now the interview for native JS and JS foundation have certain requirements, we also want to have a certain attention to this, often carry out certain training, next we will be a COLLECTION of JS common handwriting topics, master a day, handwritten code no longer panic!

Pre –

First of all, before we write code by hand, we should clarify a few questions:

  • What is anti-shake and throttling?
  • What good are they?
  • When are we going to need them?

Ok, let’s take it one problem at a time

What is anti-shake and throttling

Let’s start with a more formal answer: Shock prevention: Execute a callback function once in a specified amount of time by synthesizing events that trigger very frequently

Throttling: When events are frequently triggered, event callbacks are executed only for a specified period of time

Conclusion: In fact, anti-shake and throttling are two different solutions to solve the problem of an event being triggered frequently in a short period of time

In fact, a good look is also good to understand, did not understand it does not matter, we give an example 🌰 :

Stabilization: suppose now by bus, many people in charge, so the driver can’t drive, wait for after passengers swiped, the driver needs to wait for a while after (latency) confirmed that the passengers are ready for driving, just have a passengers get on the bus at this time, the driver had to wait for credit card substitution again sit before driving

Throttling: We all know that when the faucet is tightened, he is not completely watertight, and we find that he will drip a little water every once in a while

OK, carefully taste, should be quite understandable ~

I’m going to show you my code

Image stabilization

If the event is triggered again within the specified time, the callback will start again based on that time

The idea is to see if there is a trigger before executing the callback. If there is, we will clear the timer and start again. Our code is as follows:

const debounce = (fn, delayTime) = > {
  let timerId
  return function () {
    let th = this
    let args = arguments
    timerId && clearTimeout(timerId)
    timerId = setTimeout(() = > fn.apply(th, args), delayTime)
  }
}
Copy the code

In fact, this is the most common implementation of anti-shake, but let’s take a look at the code and do you see a problem? He waits for the delay before executing the event. What if I only fire once in total? In this case, the trigger will have to wait for a delay before firing, which is obviously not good.

In fact, there are two forms of anti-shake: non-immediate anti-shake and immediate anti-shake. As the name implies, the difference between them is that their first implementation is not immediate. This implementation is obviously non-immediate anti-shake, so how should immediate anti-shake be implemented?

In fact, it is very simple, just change the code:

const debounce = (fn, delayTime) = > {
  let timerId
  return function () {
    let th = this
    let args = arguments
    // Execute the callback for the first time. If the callback is not executed, retry the timer
    timerId == null ? fn.apply(th, args) : clearTimeout(timerId)
    timerId = setTimeout(() = > fn.apply(th, args), delayTime)
  }
}
Copy the code

Knowing the definition and how to implement it, can we imagine business scenarios that we can use in our daily development, such as:

  • Search box search, we only need the user after typing, and then send the request
  • The browser window size changes. Can we wait for the change to complete and then calculate the window size to prevent repeated rendering
  • The text editor saves in real time, waiting for a delay after any operation
  • For example, the “like” function of some applications needs to take effect immediately after being clicked, but if the user keeps clicking, we can do anti-shake operation

Ok, now let’s look at throttling

The throttle

Throttling If the event is triggered within a specified time, the callback function will be executed only when the event interval is greater than or equal to the specified time

Throttling can be implemented in two ways: timer and timestamp. Let’s take a look at both

Timer mode:

const throttle = (fn, delayTime) = > {
  let timerId
  return function() {
    let th = this
    let args = arguments
    if(! timerId) { timerId =setTimeout(() = > {
        timerId = null
        fn.apply(th,args)
      }, delayTime)
    }
  }
}
Copy the code

Timer mode: The function does not execute immediately, but waits for the delay timer to complete, so if the interval between the last triggered callback event and the previous one is less than delayTime, the last one will also execute

Let’s look at the timestamp implementation:

const throttle = (fn, delayTime) = > {
  let _start = Date.now()
  return function () {
    let th = this
    let args = arguments
    let _now = Date.now()
    if(_now - _start >= delayTime) {
      // If the time difference is greater than the wait time, the function can be called again
      fn.apply(th, args)
      // Update the timestamp of the last function execution
      _start = Date.now()
    }
  }
}
Copy the code

Time stamp: if the page is loaded and the time is greater than delayTime, fn will be executed immediately when the event callback is triggered for the first time. If the difference between the last triggered callback and the previous triggered callback is less than delayTime, the last triggered callback will not be triggered

After looking at the two methods of throttling, we found that each method has its own disadvantages, but they complement each other perfectly. Then we will combine these two methods to achieve a better throttling method:

Let’s look at the implementation code:

const throttle = (fn, delayTime) = > {
  let timerId, _start = Date.now()
  return function() {
    let th = this
    let args = arguments
    let _now = Date.now()
    let remainTime = delayTime - (_now - _start)
    if(remainTime <=0) {
      fn.apply(th,args)
      _start = Date.now()
    }else{
      clearTimeout(timerId)
      setTimeout(() = >fn.apply(th, args), remainTime) 
    }
  }
}
Copy the code

Combining the two, we found that we could execute fn the first time the event was fired, and if the last time was shorter than the last time, we could execute fn the last time after the delay had been reached

With the definition and implementation of throttling clear, let’s take a look at its business scenarios in daily development:

  • Such as our common Google search box lenovo function
  • Listen for the browser’s scroll load event
  • High frequency mouse click event (can also do anti-shake)
  • Drag and drop the animation

Well, about the anti – shake and throttling we stop here, I believe that as long as you start to write, should soon be able to master ~

At the end of the article

Welcome to pay attention to the “front-end light and shadow” public account, the public account is in the form of the system thematic module to show, so it looks more convenient, system, let us continue to learn all kinds of front-end knowledge, come on!