What are throttling and anti-shaking?

  • Throttling Throttling means that only once is triggered for a specified period of time. For example, if we set it to 500ms, the button will only trigger once no matter how many times it is clicked within this time. The scenario could be panic buying, where there are millions of people clicking on the button quickly, which would put a lot of pressure on the server to send requests every time we click, but by throttling, we can greatly reduce the number of requests.

  • Anti-shake Anti-shake means that the operation is valid only if the operation is not performed again within a specified period of time. In a specific scenario, you can request the server to match the search results in real time during the keyword input in the search box. If the server does not process the search results, the content in the input box keeps changing, resulting in continuous requests. If the anti-shake processing is carried out, the result is that after we complete the input content, a certain time (say 500ms) has not entered the content again, then the request will be triggered.

Combining these two scenarios, to get back to our most practical scenario, such as preventing the form submission button from being triggered more than once, we should choose throttling over stabilization.

1. If you

  • Principle: if it is not triggered again within the specified time, it is judged to be valid

  • Usage Scenarios:

    • Search association scenario: Only the last input is sent to prevent multiple requests
  • Simplified version implementation

// debounce(function name, shock time)
function debounce(func, wait) {
    let timeout;
    return function() {
        const context = this;
        const args = arguments;
        if (timeout) clearTimeout(timeout);
        timeout = setTimeout(function() { func.apply(context, args) }, wait); }}Copy the code
  • Implement the release immediately
    • Sometimes you want to execute the function immediately and wait n seconds after it stops firing before it can be triggered again
// Sometimes you want to execute the function immediately and wait n seconds after it stops firing before it can be triggered again
// debounce(function name, buffer time, whether to execute immediately)
function debounce(func, wait, immediate) {
    let timeout;
    return function() {
        const context = this; // Save the current execution environment this
        const arges = arguments; // Save the current function class array parameters
        if (timeout) clearTimeout(timeout); // If a timer exists, clear it first
        // Execute immediately
        if (immediate) {
            constcallNow = ! timeout; timeout =setTimeout(function() {
                timeout = null;
            }, wait)
            if (callNow) func.apply(context, arge)
        } else {
            timeout = setTimeout(function() { func.apply(context, arge) }, wait); }}}Copy the code
  • Return value version implementation
  • funcThe function may return a value, so you need to return the function result, but whenimmediateforfalseShould be usedsetTimeoutAnd we willfunc.apply(context, args)Assigns the return value to the variable, and finallyreturnThe value will always be zeroundefined, so only inimmediatefortrueReturns the result of the function’s execution
// Return value version, immediate must be true
// debounce(function name, throttling time, true)
function debounce(func, wait, immediate) {
    let timeout, result;
    return function() {
        const context = this;
        const args = arguments;
        if (timeout) clearTimeout(timeout);
        if (immediate) {
            constcallNow = ! timeout; timeout =setTimeout(funciton() {
                timeout = null;
            }, wait)
            if (callNow) result = func.apply(context, args)
        }
        else {
            timeout = setTimeout(function() {
                func.apply(context, args)
            }, wait);
        }
        returnresult; }}Copy the code

2. The throttle

Principle: Trigger only once within a specified time

  • Applicable scenario

    • The form submission
    • Drag scenario: Perform this operation only once within a fixed period to prevent uHF position changes
    • Zoom scene: Monitor the browserresize
  • Use a timestamp implementation

    • With timestamps, when the event is triggered, we take the current timestamp, subtract the previous timestamp (initially set to 0), execute the function if it is greater than the period set, then update the timestamp to the current timestamp, if it is less than the current timestamp, do not execute.
function throttle(func, wait) {
    let context, args;
    let previous = 0;
    
    return function() {
        // The current timestamp
        let now = +new Date(a);Let now = new Date().gettime ()
        context = this;
        args = arguments;
        // Current timestamp - previous timestamp
        if(now - previous > wait) { func.apply(context, args); previous = now; }}}Copy the code
  • Using timer implementation
    • When the event is triggered, a timer is set. When the event is triggered, if the timer exists, it is not executed until the timer runs out. 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 context = this;
        const args = arguments;
        if(! timeout) { timeout =setTimeout(function() {
                timeout = null;
                func.apply(context, args)
            }, wait)
        }
    }
}
Copy the code

Stabilization instance

// debounce.js

let timeout = null;

/** * Function ** is executed only after the last operation within a specified period of time@param {Function} Func Specifies the callback function to execute@param {Number} Wait delay *@param {Boolean} Immediate Whether to execute * immediately@return null* /
function debounce(func, wait = 500, immediate = false) {
	// Clear the timer
	if(timeout ! = =null) clearTimeout(timeout);
	// Execute immediately
	if (immediate) {
		varcallNow = ! timeout; timeout =setTimeout(function() {
			timeout = null;
		}, wait);
		if (callNow) typeof func === 'function' && func();
	} else {
		// Set the timer so that the timeout will not be cleared after the last operation, so execute the func callback after the wait milliseconds
		timeout = setTimeout(function() {
			typeof func === 'function'&& func(); }, wait); }}export default debounce

Copy the code