Skip to content

前言

界面供用户频繁操作的地方,如果不加以限制,频繁操作增加服务器压力,服务器响应不及时,后端接口出现异常随之带来就是后端处理逻辑抛出异常。

有以下情景:

  • 网站点击按钮,用户疯狂点击(click);
  • 界面频繁滚动(scroll);
  • 频繁调整窗口(resize);
  • 网站搜索框输入,下面显示有关内容列表(keyup);
  • 用户操作拖拽(drag);

遇到以上问题,可以使用网络请求性能 — 节流与防抖来解决。

节流

理解:预定义一个函数,只有在大于或等于执行周期才能执行,在周期内不执行。

实现:

  • 使用时间戳判断是否到达回调函数执行时间,记录上一次时间戳;
  • 每次触发事件,回调函数判断当前时间戳与上次执行时间戳间隔是否到达指定时间;
  • 如果是,则执行,并更新上一次执行时间,进行下次循环,如此反复进行。

相关代码:

<div id="price"></div>
<button id="btn">click me</button>

var Div = document.getElementById('price'), 
    Btn = document.getElementById('btn');

 function throttle(handle, wait) {
   var lastTime = 0;
   var arg = arguments;
   return function() {
     var nowTime = new Date().getTime();
     if(nowTime - lastTime > wait) {
       handle.apply(this, arg);
       lastTime = nowTime;
     }
   }
 }
 function pay() {
   Div.innerText = parseInt(Div.innerText) + 1;
 }
 Btn.onclick = throttle(pay, 1000);
<div id="price"></div>
<button id="btn">click me</button>

var Div = document.getElementById('price'), 
    Btn = document.getElementById('btn');

 function throttle(handle, wait) {
   var lastTime = 0;
   var arg = arguments;
   return function() {
     var nowTime = new Date().getTime();
     if(nowTime - lastTime > wait) {
       handle.apply(this, arg);
       lastTime = nowTime;
     }
   }
 }
 function pay() {
   Div.innerText = parseInt(Div.innerText) + 1;
 }
 Btn.onclick = throttle(pay, 1000);

防抖

理解:函数频繁触发情况下,只有足够空闲时间,才执行一次。

实现:

  • 创建一个定时器,指定时间间隔之后执行回调函数;
  • 在第二次执行回调函数时,清除前一次的定时器并设置一个新定时器;
  • 如果前一个定时器执行过了,回调函数就不能执行;
  • 如果前一个定时器未执行,将替换为一个新的定时器,延迟一定时间再执行。

相关代码:

<input type="text" id="search" />
var search = document.getElementById('search');
function debounce(handle, wait) {
  var timer = null;
  var arg = arguments;
  return function() {
    clearTimeout(timer);
    timer = setTimeout(function() {
      handle.apply(this, arg)
    }, wait)
  }
}

function ajax(arg) {
  console.log(arg.target.value);
}

search.onkeyup = debounce(ajax, 1000);
<input type="text" id="search" />
var search = document.getElementById('search');
function debounce(handle, wait) {
  var timer = null;
  var arg = arguments;
  return function() {
    clearTimeout(timer);
    timer = setTimeout(function() {
      handle.apply(this, arg)
    }, wait)
  }
}

function ajax(arg) {
  console.log(arg.target.value);
}

search.onkeyup = debounce(ajax, 1000);