Function stabilization and throttling are very similar concepts, but they are used in different scenarios.

The purpose of both anti-shake and throttling is to solve performance problems caused by a large number of functions being triggered in a short period of time, such as too high trigger frequency resulting in response speed not keeping up with the trigger frequency, delay, false death, or stalling.

They address different business requirements, so the principles of implementation are different.

A, stabilization,

The concept of function debounce is derived from the “debounce” of mechanical switches and relays. The basic idea is to combine multiple signals into one signal.

Definition: Execute the callback function n seconds after the event is triggered. If it is triggered again within n seconds, the timer is reset. This can be used on some click-request events to avoid sending multiple requests to the back end because the user clicks multiple times.

Application scenarios: (1) After the user enters a string of characters in the input box, only the last query request is executed after the input, which can effectively reduce the number of requests and save request resources. (2) Window resize, scroll events, constantly adjust the size of the browser window or scroll will trigger the corresponding events, so that it can only trigger once;

Implementation:

@param {*} delay (500) */ function debounce (fun, Delay) {let deferTimer = null return function (args) {let [that, _args] = [this, args] All clear the current timeer, Then rewrite the set timeout call deferTimer | | (clearTimeout (deferTimer), deferTimer = null) deferTimer = setTimeout(function () { fun.call(that, _args) }, Delay)}} const doSearch = () => {let debounceSearch = null DebounceSearch) {debounceSearch = debounce(doSearch, 800)} debounceSearch() // callCopy the code

Code description:

1. Each time an event is triggered, the current deferTimer is cleared and the timeout call is reset. This causes each high frequency event to cancel the previous timeout call, causing the event handler not to fire; 2. Only when the high-frequency event stops, the timeout call triggered by the last event can be executed after the delay time.

Second, the river closure

Definition: specifies a unit of time in which only one callback can be executed. If an event is triggered more than once in the same unit of time, only one callback can take effect. Throttling can be used to reduce the frequency of event calls through event throttling on scroll function event listeners.

Application scenarios: (1) Such as resize, TouchMove, Mousemove, Scroll… These trigger events continuously, only once per unit of time; (2) In the page infinite loading scenario, users need to send a request every once in a while while scrolling the page, rather than request data when users stop scrolling the page; (3) Monitor for rolling events, such as whether you are sliding to the bottom to automatically load more, using throttle;

Implementation:

@param {*} delay (300) */ export function throttle (fun, Delay = 300) {let [last, deferTimer] = [", null] return function (args) {let [that, _args] = [this, delay [last, deferTimer] = [", null] return function (args) { Args] // get the current time (ms) let now = +new Date() // +new Date() call date.prototype valueOf; '+' to convert the data types for the Number/type / / new Date (). The getTime () = = = new Date (). The valueOf () if (last && now < last + delay) {deferTimer | | (clearTimeout(deferTimer), deferTimer = null) deferTimer = setTimeout(function () { last = now fun.applay(that, _args) }, delay) } else { last = now fun.applay(that, @param {*} delay (300) */ export function throttle2 (fun, fun) Delay = 300) {let canRun = true return function (args) {let [that, _args] = [this, args] if (! canRun) return canRun = false setTimeout(() => { fun.apply(that, _args) canRun = true }, }} /** ** @param callback */ const monitorWinScroll = function (callback) {// Throttle (action) {window.requestAnimFrame = (function () {return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60) } })() let isRunning = false return function () { if (isRunning) return isRunning = true window.requestAnimFrame(() => { action() isRunning = false }) } } if (document.addEventListener) { document.addEventListener('scroll', throttle(() => { if (callback) callback(true) }), } else {$(window).scroll(throttle(() => {if (callback) callback(true)})} $(window).scroll(' window ', Throttle (function () {const pageHeight = $('body').height(); // throttle(function () {const pageHeight = $('body'). const scrollTop = $(window).scrollTop(); const winHeight = $(window).height(); const thresold = pageHeight - scrollTop - winHeight; if (thresold > -100 && thresold <= 20) { console.log('end'); }}));Copy the code

The following example returns the same effect:

+new Date()          // -> 1626919955618
new Date().getTime() // -> 1626919955618
new Date().valueOf() // -> 1626919955618
new Date()*1         // -> 1626919955618
Copy the code

The difference between anti-shake and throttling:

Anti-shake and flow closure effect:

Function stabilization is executed only once in a certain period of time; Function throttling, on the other hand, is executed at intervals in units of time. No matter how frequently an event is triggered, it is guaranteed to be executed once within a specified time.

Principle of shaking prevention and flow closure:

Anti-shake maintains a timer that fires the function after the delay, but any time that the deferTimer is triggered again, it clears the current deferTimer and resets the timeout call to reset the timer. Only the last operation can be triggered.

Throttling triggers a function by determining whether a certain time has been reached. If it has not, a timer is used to delay it. The next event will reset the timer.