首先我们要了解节流和防抖是用来处理什么问题的:

待解决问题1:
如果实现了dom拖拽功能,但是在绑定拖拽事件的时候发现每当元素稍微移动一点便触发了大量的回调函数,导致浏览器直接卡死,这个时候怎么办。
待解决问题2:
如果给一个按钮绑定了表单提交的post事件,但是用户有些时候在网络情况极差的情况下多次点击按钮造成表单重复提交,如何防止多次提交的发生?

为了应对如上场景,便出现了函数防抖和函数节流俩个概念。
总的来说:
这两个方法是在时间轴上控制函数的执行次数。

函数防抖(debounce)

概念:
在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
生活中的事例:
如果有人进电梯(触发事件),那电梯将在10秒钟后出发(执行事件监听器),这时如果又有人进电梯了(在10秒内再次触发该事件),我们又得等10秒再出发(重新计时)。
应用场景:
给按钮加函数防抖组织表单多次提交
对于输入框连续输入进行AJAX验证时,用函数防抖能有效减少请求次数
判断scroll是否滑倒底部,滚动事件+函数防抖
总结:
函数防抖适合多次事件一次响应的情况
函数防抖是指一定时间内js方法只跑一次。前一次没结束,后一次触发会按后一次的新间隔时间计算。比如按钮持续点击的限速。
代码实现:

  1. 闭包实现方法:
let timeout = null;
// 防抖函数,延迟一段时间后执行函数,如果时间内又触发了那么从新计时
function debounce(fn, wait) {
    return (args) => {
        if (timeout !== null) {
            clearTimeout(timeout)
        }
        timeout = setTimeout(() => fn(args), wait)
    }
}
function handle(args) {
  console.log(args)
  console.log('处理函数', Math.random())
}
debounce(handle, 1000)({ id: 'name' });

函数节流(throttle)

概念:
规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。
生活中的实例:
我们知道目前的一种说法是当 1 秒内连续播放 24 张以上的图片时,在人眼的视觉中就会形成一个连贯的动画,所以在电影的播放(以前是,现在不知道)中基本是以每秒 24 张的速度播放的,为什么不 100 张或更多是因为 24 张就可以满足人类视觉需求的时候,100 张就会显得很浪费资源。
应用场景:
游戏中的刷新率
DOM元素拖拽
Canvas画笔功能
总结:
函数节流适合大量事件按时间做平均分配触发
函数节流是指一定时间内js方法只跑一次。前一次没结束,后一次不会跑。比如滚动条这种持续按频率触发。
代码展示:

let _lastTime = null;
// 节流函数,规定时间内只触发一次
function throttle(fn, gapTime) {
    return (args) => {
        let _nowTime = + new Date();
        if (_nowTime - _lastTime > gapTime || !_lastTime){
            fn(args);
            _lastTime = _nowTime
        }
    }
}

throttle(handle, 1500)({ 1: 2 });