防抖和节流

De-bounce vs throttle
从优化性能入手,减少系统资源消耗
防抖 De-bounce
. 防止事件处理函数 频繁 触发
. 借助定时器实现 - 每次事件更新都重置定时器;事件停止后一定时间才触发事件处理函数
. 事件处理函数结束完毕后,重置定时器,等待下一个事件过程
. 只执行最后一次处理
[] 搜索场景中,不需要每次keyup都触发检索事件处理
. 设置定时器,每次事件触发时,就检查定时器是否启用,如果启用,说明事件还在持续中,不应该触发事件处理函数,所以应该:清空定时器,并再重新开启定时;只有当事件触发后一定时间,没有再检测到事件,才触发事件处理函数
let timer = null;
el.addEventListener('keyup', (e) => {
    if (timer) {
        clearTimeout(timer);
    }
    timer = setTimeout(() => {
        console.log(el.value);
        timer = null;
    }, 500)
})
. 封装防抖函数 - 采用闭包的形式
function Debounce(fn, delay = 500) {
    let timer = null;
    return function () {
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments);
            timer = null;
        }, delay)
    }
}

el.addEventListener('keyup', Debounce(() => {
    console.log(el.value);
}, 500))
节流 throttle
. 防止事件处理函数 马上 触发
. 借助定时器实现
. 按照固定时间间隔触发;事件发生过程中,如果定时器已经启用,则返回直到定时器到时才触发事件处理函数
. 事件处理结束完毕后,重置定时器,等待下一个事件过程
. 按照固定时间间隔开门放水,不随便放水,所以叫节流
. 事件处理函数结束完毕后,重置定时器,等待下一个事件过程
. 应用场合:鼠标拖拽 drag、鼠标移动 mousemove、屏幕缩放 resize、屏幕滚动 scroll、快速点击、下列刷新等
. 更多细节,请参考 Throttle
以下时间处理采用onXXX的形式
[] mousemove
. 不做任何处理,鼠标移动时频繁触发
window.onmousemove = function (e) {
    console.log(e.clientY);
}
. 借助定时器采用节流措施;一般延时100ms,为了直观,采用500ms
let timer = null;
window.onmousemove = function (e) {
    if (timer) {
        return;
    }
    timer = setTimeout(() => {
        console.log(e.clientY);
        timer = null;
    }, 500)
}
. 封装节流函数
function Throttle(fn, delay = 100) {
    let timer = null;
    return function () {
        if (timer) {
            return;
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments);
            timer = null;
        }, 500)
    }
}
window.onmousemove = Throttle((e) => {
    console.log(e.clientY);
}, 500)