js 的 节流 和 防抖

目录

节流 和 防抖 简介

在用户进行浏览器页面的操作时,可能会发生一段时间内(如1s内),连续、频繁点击某个操作按钮,导致频繁操作dom或者向后台发出请求,可能会造成页面卡顿或者服务器拥堵。针对此种情况,可以使用js的 节流 和 防抖 来解决。

节流 和 防抖 这两种方式的实现原理都是利用 setTimeOut 定时器来实现的,将用户的操作延迟执行。

节流 和 防抖 区别

节流,采用“间隔一段时间后执行”,即 第一次触发时,先创建一个定时器,在一定时间后再执行触发事件,同时将定时器置为空,若在一定时间内(比如1s内)再次触发,则会判断定时器是否存在,如果存在,则不再创建新的定时器(后续的触发事件不会执行);

防抖,采用“延迟执行触发,并清除上一次的定时器”,即 第一次触发时,先创建一个定时器,在一定时间后再执行触发事件,若在一定时间内(比如1s内)再次触发,则会清除之前的定时器,重新新建一个定时器;这样会有一个缺点,就是 若在一段时间内不停地触发事件,那么该事件的执行会被无限期地延后。

应用场景

  1. 节流

    • 防止表单提交时重复多次触发事件;
  2. 防抖

    • 窗口resize需计算窗口的大小时,需等用户的拖拽事件完成后执行计算方法;

    • input 输入框的实时查询事件,在用户不断输入的过程中不触发查询,等用户输入完停止一段时间后再触发

代码实现

  • 节流
function clickFn() {
  console.log('clickFn');
}

// 节流,一段时间内只能触发一次函数,若触发多次,则只有一次生效(相当于执行这段时间内第一次点击的事件)
function dealFn(func, time) {
  let timer = null;
  return function() {
    let that = this;
    if(!timer) {
      timer = setTimeout(() => {
        func.call(that);
        timer = null;
      }, time)
    }
  }
}

let submitClick = dealFn(clickFn, 1000);

submitClick();
submitClick();
setTimeout(()=> {
  console.log("...");
  submitClick();
}, 1000);
  • 防抖
function clickFn() {
  console.log('clickFn');
}

// 防抖,一段时间内触发多次函数时,每次触发都延迟函数调用,并在下一次触发时清除之前的定时器(相当于执行这段时间内最后一次点击的事件)
// 每次触发事件时设置一个延迟调用方法,并且取消之前的延时调用方法
// 缺点:如果事件在规定的时间间隔内被不断的触发,则调用方法会被不断的延迟
function dealFn(func, time) {
  let timer = null;
  return function() {
    let that = this;
    clearTimeout(timer);
    timer = setTimeout(() => {
      func.call(that);
    }, time)
  }
}

let submitClick = dealFn(clickFn, 1000);

submitClick();
submitClick();
setTimeout(()=> {
  console.log("...");
  submitClick();
}, 1000);

扩展知识点

1、call 和 apply

详见 javaScript---bind、call、apply

2、闭包

之所以在后续的方法调用(submitClick())时,能删除之前调用时定义的 timer,是因为 js 的闭包,使得对于这些调用来说,timer 成为了一个“全局变量”。

详见 javaScript 中的闭包

上一篇:NSTimer 的正确用法你真的知道吗?


下一篇:C# Windows Service入门