1

使用场景

某些场景下,一些计算量比较大的函数,操作 DOM 函数等函数会被频繁调用执行,而且由于人的反应有限实际不需要那么多计算,就会造成极大的性能浪费。
举个例子
当使用鼠标滚轮时可以轻松触发每秒30个事件。但是,我在测试中,智能手机中的慢速滚动可能会触发每秒多达100个事件。你的滚动处理程序是否真的需要这个执行速度?
下面我列举一些场景

  1. window对象的resize、scroll事件,如处理图片懒加载
  2. 拖拽时的mousemove事件
  3. 键盘 keyup 事件
  4. ...

原理

那么throttle 和 debounce 函数是怎样做的呢?
这里引用经典的举例

想象每天上班大厦底下的电梯。把电梯完成一次运送,类比为一次函数的执行和响应。假设电梯有两种运行策略 throttle 和 debounce ,超时设定为15秒,不考虑容量限制。
1.throttle 策略的电梯。保证如果电梯第一个人进来后,15秒后准时运送一次,不等待。如果没有人,则待机。
2.debounce 策略的电梯。如果电梯里有人进来,等待15秒。如果又人进来,15秒等待重新计时,直到15秒超时,开始运送。

用我的一句话说是,throttle 在一段时间内最多执行一次,而 debounce 是在接下来一段时间内没有再次调用,则执行。

实现

由于说了是简单实现,那么就把最核心的部分拿出来

debounce

function debounce (cb, delay) {
    var timer = null;
    return function () {
        clearTimeout(timer);
        timer = setTimeout(cb, delay);
    }
}

throttle

function throttle (cb, delay) {
    var lastTime = Date.now();
    return function () {
        var nowTime = Date.now();
        if (nowTime - lastTime > delay) {
            cb();
            lastTime = nowTime;
        }
    }
}

可以看下效果
查看链接

知道原理之后,想要使用,现在很多库都有这个功能

  1. jquery 插件 jQuery throttle / debounce
  2. Underscore 库 _.throttle 和 _.debounce
  3. lodash 库 _.debounce 和 _.throttle

leizore
131 声望2 粉丝

好看的皮囊千篇一律,有趣的灵魂万里挑一