preface

If you often “walk” in some technical community, the two words “anti-shock” and “throttling” of functions are mentioned quite frequently, but I have done a year of development, but I did not use them in my own project, or I should think about it. Forget the pain and study hard.

Image stabilization (debounce)

The principle of 🍖

The event is executed n seconds before the callback is executed. If it is triggered again within n seconds, the n seconds are recalculated.

Application Scenarios 🍔

  • Search box: user input keywords to trigger the search behavior;
  • Window resize event: trigger the corresponding operation after the user has resized;

Results the preview

  • Before the image stabilization
<input id="debounce"> < / input > search boxfunction search(e) {
    console.log('Start searching' , e.target.value)
}
const de = document.getElementById('debounce')
de.addEventListener('input', search)
Copy the code
  • After being

<input id="debounce"> < / input > search boxfunction search(e) {
    console.log('Start searching' , e.target.value)
}

function debounce(fn, delay) {
    let ts = null
    console.log('debounce')
    return function() {
        clearTimeout(ts)
        ts = setTimeout(() => {
            fn.apply(this, arguments)
        }, delay)
    }
} 
const de = document.getElementById('debounce')
de.addEventListener('input', debounce(search, 1000))
Copy the code

Is it really understood? 👺 (thinking)

  • Why is the debounce string printed only once?

When the addEventListener is bound, the return value of debounce is used, which is easy to understand compared to before the shock protection.

  • Why fn.apply(this, arguments) instead of fn()?

In fact, in the current program, we can use fn(… Argruments) instead of fn. Apply (this, arguments), because we don’t use this in search either. Call (fn. Call (this,… arguments)

  • Why is the arrow function used in setTimeout?

The arrow function doesn’t have this. If you don’t use the arrow function, this would point to setTimeout

function debounce(fn, delay) {
    let ts = null
    console.log('debounce')
    return function() {
        clearTimeout(ts)
        const context = this, args = arguments
        ts = setTimeout(function() {
            fn.apply(context, args)
        }, delay)
    }
} 
Copy the code

The throttle (throttle)

The principle of 🍖

The event is executed n seconds before the callback is executed. If the event is triggered again within n seconds, the callback is ignored. Generally speaking, it is like the cooldown time of hero skill in king of Honor, until the cooldown time, how you point is no effect.

Application scenarios

  • Form submission: Click the submit button multiple times
  • Scroll event: Request more data when the scroll bar slides to the bottom

Effect preview (the effect before throttling is shown in the front, we directly look at the effect after throttling)

// Code preview 🍔function throttle(fn, delay) {
    let ts = null
    return function() {
        if(! ts) { ts =setTimeout(() => { fn.call(this, ... arguments) ts = null }, delay) } } }Copy the code

Questions to consider 👺

  • Often what we want is for button clicks to be performed immediately, and throttling to happen after the first time, so let’s optimize the code a little bit
function throttle(fn, delay) {
    let ts = null
    let first = true
    return function() {
        if(first) { fn.call(this, ... arguments) first =false
        }
        if(! ts) { ts =setTimeout(() => { fn.call(this, ... arguments) ts = null }, delay) } } }Copy the code
  • Now let’s see what happens

Summary and Reflection

  • Anti-shock and throttling seem to be simple functions, but they cover a lot of basic knowledge. We might as well think about closure, function scope, this pointing and other issues
  • Think about why we didn’t use them in our project and whether to add them later as an optimization.