防抖和节流

3 阅读2分钟

防抖

举个栗子

假如你在开发一个搜索功能,搜索框输入文字的时候,需要调用后端接口获取搜索建议。

于是你:“这还不是砍瓜切菜!”

  1. 先获取输入框
  2. 注册input事件回调
  3. 写好所需的回调函数

一顿操作后代码如下:

//获取搜索框
var search_input = document.querySelector('.search_input')

//注册input事件回调
search_input.addEventListener('input',getSeachAdvices)

//获取搜索建议
function getSeachAdvices(){
    //发送网络请求
    ......
}

完工!你开始测试功能,搜索框里一顿输入,看起来功能没啥问题,此时一不小心打开控制台,我去!这么多网络请求!!!

问题所在是:input事件会在输入过程中不停触发,你的回调函数会不停的被调用,调用一次就发送一次网络请求。。。

这像不像你的手一直在抖动的按下按钮?

而其实你只需要在输入完成后只请求一次最终的结果就行了。

换句话说,你不需要在每次键盘按下都调用回调函数,而是在最后一下输入之后调用即可。

怎么实现呢?

你心生一计:我能不能在每次触发事件的时候,让回调函数先不立即执行,而是先等待个一段时间(比如1s)再执行?如果等待期间有新输入触发事件,我就再重新等待一段时间(1s)后执行回调?

恭喜你,这就是防抖的思想。

代码实现

//获取搜索框
var search_input = document.querySelector('.search_input')

//注册input事件回调
search_input.addEventListener('input',debounce(getSeachAdvices))

//获取搜索建议
function getSeachAdvices(){
    //发送网络请求
    ......
}

function debounce(fn,delay){
    var timerId
    return function(){
        if(timerId){
            clearTimeout(timerId)
        }
        let args = Array.prototype.slice.call(arguments)
        var _this = this
        timerId = setTimeout(function(){
            fn.apply(_this,args)
        },delay)
    }
}
防抖总结:
  • 手别乱抖!啥时候不抖了我再执行~
  • 先让子弹飞一会~等你消停了我再干活~
  • 多次触发,一次执行!
典型场景
  • 搜索框输入
  • 窗口resize