1) stabilization

  • How it works: The callback is executed n seconds after the event is triggered. If it is triggered again within n seconds, the timer is reset.
  • Applicable scenarios:
    • Button submission scenario: Prevents multiple button submissions and only performs the last submission
    • Search box continuous scenario: To prevent continuous requests, only the last input is sent
  • Simplified version implementation
function debounce(func, wait) {
    let timeout
    return function() {
        const ctx = this
        const args = arguments
        clearTimeout(timeout)
        timeout = setTimeout(function(){
            func.apply(ctx, args)
        }, wait)
    }
}
Copy the code
  • Implement the release immediately
// Sometimes we want to execute the function immediately and wait n seconds before we can trigger it again.
function debounce(func, wait, immediate) {
    let timeout
    return function() {
        const ctx = this
        const args = arguments
        if(timeout) clearTimeout(timeout)
        if(immediate) {
            constcallNow = ! timeout timeout =setTimeout(function() {
                timeout = null
            }, wait)
            if(callNow) func.apply(ctx, args)
        } else {
            timeout = setTimeout(function() {
                func.apply(ctx, args)
            }, wait)
        }
    }
}
Copy the code
  • Return value version implementation

The func function may return a value, so we need to return the result of the function, but when immediate is false, because setTimeout is used, we assign the return value of func. Apply (CTX, args) to the variable, and then return. The value will always be undefined, so return the result of the function only if immediate is true.

function debounce(func, wait, immediate) {
    let timeout, result
    return function() {
        const ctx = this
        const args = arguments
        if(timeout) clearTimeout(timeout)
        if(immediate) {
            constcallNow = ! timeout timeout =setTimeout(function() {
                timeout = null
            }, wait)
            if(callNow) result = func.apply(ctx, args)
        } else {
            timeout = setTimeout(function() {
                func.apply(ctx, args)
            }, wait)
        }
        
        return result
    }
}
Copy the code

2) the throttle

  • Principle: Specifies that only one function can be triggered in a unit of time. If more than one function is fired in this unit of time, only one function will take effect.
  • Applicable scenarios:
    • Drag scenario: Perform this operation only once within a fixed period to prevent uHF position changes
    • Zoom scenario: Monitor browser resize
  • Use a timestamp implementation

With timestamps, when the event is triggered, we remove the current timestamp, subtract the previous timestamp (initially set to 0), execute the function if it is greater than the period set, and then update the timestamp to the current timestamp. If it is less than the current timestamp, we do not execute.

function throttle(func, wait) {
    let ctx, args
    let previous = 0
    return function() {
        let now = +new Date()
        ctx = this
        args = arguments
        if(now - previous > wait) {
            func.apply(ctx, args)
            previous = now
        }
    }
}
Copy the code
  • Using timer implementation

When the event is triggered, we set a timer, and when the event is triggered, if the timer exists, it is not executed until the timer is executed, and then the function is executed to clear the timer so that the next timer can be set.

function throttle(func, wait) {
    let timeout
    return function() {
        const ctx = this
        const args = arguments
        if(! timeout) { timeout =setTimeout(function() {
                timeout = null
                func.apply(ctx, args)
            }, wait)
        }
    }
}
Copy the code