The premise

  • The purpose of anti-shaking and throttling is to make a function occur less frequently, and sometimes meaningless functions (such as requests for data) occur too frequently and cause great strain on the server

Specific case

// This event will continue to be triggered when the keyboard is pressed // requirement: we don't need to trigger this event every time the user stops pressing // Specify requirement: <input id="ipt1" /> ipt1. onkeyDown = function(){console.log(e.target.value); }Copy the code

Simple version of anti-shake

  • Principle: use timer to achieve, small tip: timer variable is a self-increasing number of display
let ipt1 = document.querySelector("#ipt1"); Let timer = null ipt1. onKeyDown = function(e){// If there was a timer before, cancel the timer timer && clearTimeout(timer); Timer = setTimeout(()=>{console.log(timer); / / 1, 2, 3... console.log(e.target.value); }}, 500)Copy the code

Let’s take a look at the process:

  1. When onKeyDown is triggered for the first time, a 0.5s A timer is started
  2. If the second onKeyDown is triggered within 0.5s, then timer A is cancelled and timer B (new timer) is triggered.
  3. If the third onKeyDown is triggered within 0.5 (within.5s after the B timer is on), repeat step No.2. If the third onKeyDown is fired after 0.5s, the event execution will be triggered after that

Anti-shake – Not immediately executed

  • So, easy to complete, to encapsulate the anti – shake function.
let ipt1 = document.querySelector("#ipt1"); Function debounce(fn,wait){let timer; function debounce(fn,wait){let timer; Return function(){timer && clearTimeout(timer); // Let args = [...arguments]; // Let context = this; Timer = setTimeout(()=>{fn.apply(this,args)},wait)}} // Keydown function trigger(e){ console.log(e.target.value); } let fn = debounce(trigger,500) Ipt1. onkeydown = function(){fn('123')}Copy the code

Anti-shake. – Execute immediately

  • The above function analysis shows that it is actually a non-immediate version (triggered after pressing the keyboard for 0.5s)
  • So let’s implement an immediate execution version (triggered by pressing the keyboard)
function debounce(fn,wait){ let timer; return function(){ timer && clearTimeout(timer) let context = this; let args = [...arguments]; // let doNow =! timer; Timer = setTimeout(()=>{// Timer = null; If (doNow){fn.apply(context,this)}}}Copy the code
  • Here we can analyze the steps of the process, I believe that you understand the internal operation has great help

A merger

  • Principle: Select non-immediate or immediate versions based on the immediate variable
function finallyDebounce(fn,wait,immediate){ let timer; return function(){ timer && clearTimeout(timer) let args = [...arguments] let context = this; if(immediate){ const Now = ! timer; timer = setTimeout(()=>{ timer = null; },wait) if(Now){ fn.apply(context,args) } }else{ timer = setTimeout(()=>{ fn.apply(context,args) },wait) } } }Copy the code

Throttling function

  • If the wait is set to wait, the same effect can be achieved. However, if the wait is set to wait, the same effect can be achieved. If the wait is set to wait, the same effect can be achieved.

Throttling – Perform immediately

  • Principle: Through the timestamp to achieve
Function throttle(fn,wait){let time = 0 return function(){let now = date.now (); let args = [...arguments]; let context = this; If (now-time > wait){fn. Apply (context,args) time = now}}}Copy the code

Throttling – Not performed immediately

function throttle(fn,wait){ let timer; return function(){ let args = [...arguments]; let context = this; // In order to implement the specified time must be executed once! if(! timer){ timer = setTimeout(()=>{ fn.apply(context,this) timer = null },wait) } } }Copy the code

Shuangjian merger

function finalyThrottle(fn,wait,immediate){ if(immediate){ let time = 0; return function(){ let args = [...arguments]; let context = this; let now = Date.now() if(now - time > wait){ fn.apply(context,args) time = now; } } }else{ let timer return function(){ let args = [...arguments]; let context = this; if(! timer){ timer = setTimeout(()=>{ fn.apply(context,args); timer = null; },wait) } } } }Copy the code